瀏覽代碼

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

# Conflicts:
#	src/main/java/com/caimei365/commodity/components/PriceUtilService.java
Aslee 3 年之前
父節點
當前提交
6391107b60

+ 0 - 0
src/main/resources/backup.sql → backup.sql


+ 1 - 1
pom.xml

@@ -32,7 +32,7 @@
     <dependencies>
     <dependencies>
 		<dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-webflux</artifactId>
+			<artifactId>spring-boot-starter-web</artifactId>
 		</dependency>
 		</dependency>
 		<dependency>
 		<dependency>
 			<groupId>org.springframework.cloud</groupId>
 			<groupId>org.springframework.cloud</groupId>

+ 0 - 2
src/main/java/com/caimei365/commodity/CommodityApplication.java

@@ -7,14 +7,12 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 /**
 /**
  * `@EnableEurekaClient`: 声明一个Eureka客户端,只能注册到Eureka Server
  * `@EnableEurekaClient`: 声明一个Eureka客户端,只能注册到Eureka Server
  * `@EnableDiscoveryClient`: 声明一个可以被发现的客户端,可以是其他注册中心
  * `@EnableDiscoveryClient`: 声明一个可以被发现的客户端,可以是其他注册中心
- * `@EnableFeignClients`: 开启Feign
  *
  *
  * @author : Charles
  * @author : Charles
  * @date : 2021/2/22
  * @date : 2021/2/22
  */
  */
 @EnableDiscoveryClient
 @EnableDiscoveryClient
 @SpringBootApplication
 @SpringBootApplication
-//@EnableFeignClients
 public class CommodityApplication {
 public class CommodityApplication {
 
 
     public static void main(String[] args) {
     public static void main(String[] args) {

+ 1 - 6
src/main/java/com/caimei365/commodity/components/PriceUtilService.java

@@ -137,11 +137,6 @@ public class PriceUtilService {
                 }
                 }
                 if (promotions.getType() == 1 && promotions.getMode() == 1 && null != promotions.getTouchPrice()) {
                 if (promotions.getType() == 1 && promotions.getMode() == 1 && null != promotions.getTouchPrice()) {
                     price.setPrice(promotions.getTouchPrice());
                     price.setPrice(promotions.getTouchPrice());
-                    //添加税费
-                    if (taxFlag) {
-                        BigDecimal taxFee = MathUtil.div(MathUtil.mul(promotions.getTouchPrice(), price.getTaxRate()), 100, 2);
-                        promotions.setTouchPrice(MathUtil.add(promotions.getTouchPrice(),taxFee).doubleValue());
-                    }
                 }
                 }
                 price.setPromotions(promotions);
                 price.setPromotions(promotions);
             } else {
             } else {
@@ -173,8 +168,8 @@ public class PriceUtilService {
             //添加税费
             //添加税费
             if (taxFlag) {
             if (taxFlag) {
                 BigDecimal thisTaxFee = MathUtil.div(MathUtil.mul(price.getPrice(), price.getTaxRate()), 100, 2);
                 BigDecimal thisTaxFee = MathUtil.div(MathUtil.mul(price.getPrice(), price.getTaxRate()), 100, 2);
-                BigDecimal originalTaxFee = MathUtil.div(MathUtil.mul(price.getOriginalPrice(), price.getTaxRate()), 100, 2);
                 price.setPrice(MathUtil.add(price.getPrice(), thisTaxFee).doubleValue());
                 price.setPrice(MathUtil.add(price.getPrice(), thisTaxFee).doubleValue());
+                BigDecimal originalTaxFee = MathUtil.div(MathUtil.mul(price.getOriginalPrice(), price.getTaxRate()), 100, 2);
                 price.setOriginalPrice(MathUtil.add(price.getOriginalPrice(), originalTaxFee).doubleValue());
                 price.setOriginalPrice(MathUtil.add(price.getOriginalPrice(), originalTaxFee).doubleValue());
             }
             }
         } else {
         } else {

+ 29 - 0
src/main/java/com/caimei365/commodity/config/ApiConfig.java

@@ -0,0 +1,29 @@
+package com.caimei365.commodity.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import javax.annotation.Resource;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2020/3/12
+ */
+@Configuration
+public class ApiConfig implements WebMvcConfigurer {
+    @Resource
+    private ApiInterceptor apiInterceptor;
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        //addPathPatterns 用于添加拦截规则
+        //excludePathPatterns 用于排除拦截
+        registry.addInterceptor(apiInterceptor)
+                .addPathPatterns("/commodity/shop/product/release")
+                .addPathPatterns("/commodity/shop/product/offline");
+//                .excludePathPatterns("/order/shareCode");
+    }
+}

+ 46 - 0
src/main/java/com/caimei365/commodity/config/ApiInterceptor.java

@@ -0,0 +1,46 @@
+package com.caimei365.commodity.config;
+
+import com.caimei365.commodity.components.RedisService;
+import com.caimei365.commodity.utils.JwtUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2020/3/12
+ */
+@Component
+public class ApiInterceptor implements HandlerInterceptor {
+
+    @Value("${caimei.coreDomain}")
+    private String domain;
+
+    private RedisService redisService;
+
+    @Autowired
+    public void setRedisService(RedisService redisService) {
+        this.redisService = redisService;
+    }
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        String token = request.getHeader("X-Token");
+        if (!JwtUtil.isVerify(token)) {
+            String cacheToken = null != token ? String.valueOf(redisService.get(token)) : null;
+            if (null == cacheToken || !JwtUtil.isVerify(cacheToken)) {
+                // Token失效
+                response.sendRedirect(domain + "/commodity/unauthorized");
+                return false;
+            }
+        }
+        return true;
+    }
+
+}

+ 91 - 0
src/main/java/com/caimei365/commodity/config/GlobalTokenAspect.java

@@ -0,0 +1,91 @@
+package com.caimei365.commodity.config;
+
+import com.caimei365.commodity.components.RedisService;
+import com.caimei365.commodity.utils.JwtUtil;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 把切面类加入到IOC容器中
+ * 所有请求都会更新redis存token的时间
+ *
+ * @author : Charles
+ * @date : 2020/3/17
+ */
+@Component
+@Aspect
+public class GlobalTokenAspect {
+
+    private RedisService redisService;
+    @Autowired
+    public void setRedisService(RedisService redisService) {
+        this.redisService = redisService;
+    }
+
+    /**
+     * 定义一个切入点 我这里是从controller切入
+     */
+    @Pointcut("execution(public * com.caimei365.commodity.controller..*.*(..))")
+    public void pointCut() {
+    }
+
+    /**
+     * 前置通知
+     * 在进入方法前执行 可以对参数进行限制或者拦截
+     * 通常在这边做日志存储存到数据库中
+     * @param joinPoint
+     * @throws Throwable
+     */
+    @Before("pointCut()")
+    public void before(JoinPoint joinPoint) throws Throwable {
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        String token = request.getHeader("X-Token");
+        String cacheToken = null!=token ? String.valueOf(redisService.get(token)) : null;
+        // Redis过期后会得到"null"值,所以需判断字符串"null"
+        if (cacheToken != null && cacheToken.length() != 0 && !"null".equals(cacheToken)) {
+            if (JwtUtil.isVerify(cacheToken)) {
+                int userId = JwtUtil.parseTokenUid(cacheToken);
+                // 刷新token
+                tokenRefresh(token, userId);
+            }
+        }
+    }
+
+    /**
+     * JWT Token续签:
+     * 业务逻辑:登录成功后,用户在未过期时间内继续操作,续签token。
+     * 登录成功后,空闲超过过期时间,返回token已失效,重新登录。
+     * 实现逻辑:
+     * 1.登录成功后将token存储到redis里面(这时候k、v值一样都为token),并设置过期时间为token过期时间
+     * 2.当用户请求时token值还未过期,则重新设置redis里token的过期时间。
+     * 3.当用户请求时token值已过期,但redis中还在,则JWT重新生成token并覆盖v值(这时候k、v值不一样了),然后设置redis过期时间。
+     * 4.当用户请求时token值已过期,并且redis中也不存在,则用户空闲超时,返回token已失效,重新登录。
+     */
+    public boolean tokenRefresh(String token, Integer userID) {
+        String cacheToken = String.valueOf(redisService.get(token));
+        // 过期后会得到"null"值,所以需判断字符串"null"
+        if (cacheToken != null && cacheToken.length() != 0 && !"null".equals(cacheToken)) {
+            // 校验token有效性
+            if (!JwtUtil.isVerify(cacheToken)) {
+                // 生成token
+                String newToken = JwtUtil.createToken(userID);
+                // 将token存入redis,并设置超时时间
+                redisService.set(token, newToken, JwtUtil.getExpireTime());
+            } else {
+                // 重新设置超时时间
+                redisService.set(token, cacheToken, JwtUtil.getExpireTime());
+            }
+            return true;
+        }
+        return false;
+    }
+}

+ 0 - 21
src/main/java/com/caimei365/commodity/config/LoadBalanceConfiguration.java

@@ -1,21 +0,0 @@
-package com.caimei365.commodity.config;
-
-import org.springframework.cloud.client.loadbalancer.LoadBalanced;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.reactive.function.client.WebClient;
-
-/**
- * Description
- *
- * @author : Charles
- * @date : 2021/2/23
- */
-@Configuration
-public class LoadBalanceConfiguration {
-    @Bean
-    @LoadBalanced
-    public WebClient.Builder builder() {
-        return WebClient.builder();
-    }
-}

+ 0 - 123
src/main/java/com/caimei365/commodity/config/TokenFilter.java

@@ -1,123 +0,0 @@
-package com.caimei365.commodity.config;
-
-import com.alibaba.fastjson.JSONObject;
-import com.caimei365.commodity.components.RedisService;
-import com.caimei365.commodity.utils.JwtUtil;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.buffer.DataBuffer;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.server.reactive.ServerHttpRequest;
-import org.springframework.http.server.reactive.ServerHttpResponse;
-import org.springframework.stereotype.Component;
-import org.springframework.web.server.ServerWebExchange;
-import org.springframework.web.server.WebFilter;
-import org.springframework.web.server.WebFilterChain;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-
-/**
- * JWT Token
- *
- * 续签逻辑:
- * 登录成功后,用户在未过期时间内继续操作,续签token。
- * 登录成功后,空闲超过过期时间,返回token已失效,重新登录。
- * 实现逻辑:
- * 1.登录成功后将token存储到redis里面(这时候k、v值一样都为token),并设置过期时间为token过期时间
- * 2.当用户请求时token值还未过期,则重新设置redis里token的过期时间。
- * 3.当用户请求时token值已过期,但redis中还在,则JWT重新生成token并覆盖v值(这时候k、v值不一样了),然后设置redis过期时间。
- * 4.当用户请求时token值已过期,并且redis中也不存在,则用户空闲超时,返回token已失效,重新登录。
- *
- * @author : Charles
- * @date : 2021/3/30
- */
-@Slf4j
-@Component
-public class TokenFilter implements WebFilter {
-
-    private static final String AUTH = "X-Token";
-    /**
-     * 需要权限认证的接口路径
-     */
-    private static final String[] PERMISSION_URLS = new String[]{
-        "/commodity/shop/product/release",
-        "/commodity/shop/product/offline"
-    };
-    private RedisService redisService;
-    @Autowired
-    public void setRedisService(RedisService redisService) {
-        this.redisService = redisService;
-    }
-
-    @Override
-    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
-        ServerHttpRequest request = exchange.getRequest();
-        ServerHttpResponse response = exchange.getResponse();
-
-        HttpHeaders header = request.getHeaders();
-        String token = header.getFirst(AUTH);
-        String url = request.getURI().getPath();
-
-        if (StringUtils.isBlank(token) && Arrays.asList(PERMISSION_URLS).contains(url)) {
-            log.error("未经授权,Token为空!");
-            return tokenErrorResponse(response, "未经授权,Token为空!");
-        }
-
-        if (StringUtils.isNotBlank(token)) {
-            String cacheToken = (String) redisService.get(token);
-            // token续签
-            if (StringUtils.isNotBlank(cacheToken) && !"null".equals(cacheToken) && JwtUtil.isVerify(cacheToken)) {
-                int userId = JwtUtil.parseTokenUid(cacheToken);
-                log.debug("Token续签,UserId:"+userId+",Token:"+token);
-                // 再次校验token有效性
-                if (!JwtUtil.isVerify(cacheToken)) {
-                    // 生成token
-                    String newToken = JwtUtil.createToken(userId);
-                    // 将token存入redis,并设置超时时间(秒)
-                    redisService.set(token, newToken, JwtUtil.getExpireTime());
-                } else {
-                    // 重新设置超时时间(秒)
-                    redisService.expire(token, JwtUtil.getExpireTime());
-                }
-            } else {
-                // 需要验证的路径
-                if(Arrays.asList(PERMISSION_URLS).contains(url)) {
-                    // Token失效
-                    log.error("Token失效,token:"+token+",cacheToken:"+cacheToken);
-                    return tokenErrorResponse(response, "Token失效,请重新登录!");
-                }
-            }
-        }
-        //            //TODO 将用户信息存放在请求header中传递给下游业务
-        //            ServerHttpRequest.Builder mutate = request.mutate();
-        //            mutate.header("demo-user-name", username);
-        //            ServerHttpRequest buildReuqest = mutate.build();
-        //
-        //            //todo 如果响应中需要放数据,也可以放在response的header中
-        //            response.setStatusCode(HttpStatus.OK);
-        //            response.getHeaders().add("demo-user-name",username);
-        //            return chain.filter(exchange.mutate()
-        //                    .request(buildReuqest)
-        //                    .response(response)
-        //                    .build());
-        return chain.filter(exchange);
-    }
-
-    private Mono<Void> tokenErrorResponse(ServerHttpResponse response, String responseMsg){
-        response.setStatusCode(HttpStatus.OK);
-        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
-        JSONObject res = new JSONObject();
-        res.put("code", -99);
-        res.put("msg", responseMsg);
-        byte[] responseByte = res.toJSONString().getBytes(StandardCharsets.UTF_8);
-        DataBuffer buffer = response.bufferFactory().wrap(responseByte);
-        return response.writeWith(Flux.just(buffer));
-    }
-
-
-}

+ 8 - 0
src/main/java/com/caimei365/commodity/controller/BaseApi.java

@@ -1,5 +1,6 @@
 package com.caimei365.commodity.controller;
 package com.caimei365.commodity.controller;
 
 
+import com.caimei365.commodity.model.ResponseJson;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -27,4 +28,11 @@ public class BaseApi {
         }
         }
         return "欢迎使用!";
         return "欢迎使用!";
     }
     }
+    /**
+     * Token失效
+     */
+    @GetMapping("/unauthorized")
+    public ResponseJson<Void> unauthorized() {
+        return ResponseJson.error(-99, "Token失效请重新登录!", null);
+    }
 }
 }

+ 19 - 0
src/main/java/com/caimei365/commodity/controller/ProductPriceApi.java

@@ -1,6 +1,7 @@
 package com.caimei365.commodity.controller;
 package com.caimei365.commodity.controller;
 
 
 import com.caimei365.commodity.model.ResponseJson;
 import com.caimei365.commodity.model.ResponseJson;
+import com.caimei365.commodity.model.dto.ProductSalesDto;
 import com.caimei365.commodity.model.vo.LadderPriceVo;
 import com.caimei365.commodity.model.vo.LadderPriceVo;
 import com.caimei365.commodity.model.vo.PriceVo;
 import com.caimei365.commodity.model.vo.PriceVo;
 import com.caimei365.commodity.service.PriceService;
 import com.caimei365.commodity.service.PriceService;
@@ -11,6 +12,7 @@ import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
 
 
@@ -84,4 +86,21 @@ public class ProductPriceApi {
         return priceService.getLadderPrice(productId);
         return priceService.getLadderPrice(productId);
     }
     }
 
 
+    /**
+     * 更新商品销量
+     * @param productSalesDto {productInfo: [ // 商品id,数量
+     *                                      {"productId": 2789, "productCount": 1},
+     *                                      {"productId": 2790, "productCount": 2}
+     *                                       ]
+     *                        }
+     */
+    @ApiOperation("更新商品销量")
+    @PostMapping("/sales/update")
+    public ResponseJson<Void> productSaleUpdate(ProductSalesDto productSalesDto){
+        if (StringUtils.isEmpty(productSalesDto.getProductInfo())){
+            return ResponseJson.error("商品数据不能为空!", null);
+        }
+        return priceService.productSaleUpdate(productSalesDto.getProductInfo());
+    }
+
 }
 }

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

@@ -1,5 +1,6 @@
 package com.caimei365.commodity.mapper;
 package com.caimei365.commodity.mapper;
 
 
+import com.caimei365.commodity.model.vo.ProductSalesVo;
 import com.caimei365.commodity.model.vo.LadderPriceVo;
 import com.caimei365.commodity.model.vo.LadderPriceVo;
 import com.caimei365.commodity.model.vo.PriceVo;
 import com.caimei365.commodity.model.vo.PriceVo;
 import com.caimei365.commodity.model.vo.TaxVo;
 import com.caimei365.commodity.model.vo.TaxVo;
@@ -52,4 +53,12 @@ public interface PriceMapper {
      * 根据用户id查询超级会员用户id
      * 根据用户id查询超级会员用户id
      */
      */
     Integer getSvipUserIdByUserId(Integer userId);
     Integer getSvipUserIdByUserId(Integer userId);
+    /**
+     * 获取商品销量信息
+     */
+    ProductSalesVo getProductSalesInfo(Integer productId);
+
+    void insertProductSales(ProductSalesVo salesVo);
+
+    void updateProductSales(ProductSalesVo salesVo);
 }
 }

+ 4 - 0
src/main/java/com/caimei365/commodity/mapper/ShopMapper.java

@@ -155,4 +155,8 @@ public interface ShopMapper {
      *  获取商品小程序云上美博会活动状态
      *  获取商品小程序云上美博会活动状态
      */
      */
     Integer getAppletsBeautyStatusById(Integer productId);
     Integer getAppletsBeautyStatusById(Integer productId);
+    /**
+     * 获取供应商名称
+     */
+    String getShopNameByShopId(Integer shopId);
 }
 }

+ 27 - 0
src/main/java/com/caimei365/commodity/model/dto/ProductSalesDto.java

@@ -0,0 +1,27 @@
+package com.caimei365.commodity.model.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2021/10/11
+ */
+@ApiModel("商品销量")
+@Data
+public class ProductSalesDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * 商品信息:[ // 商品id,数量
+     *         {"productId": 2789, "productCount": 1},
+     *         {"productId": 2790, "productCount": 2}
+     *         ]
+     */
+    @ApiModelProperty("商品信息[{\"productId\": 2789, \"productCount\": 1},{}]")
+    private String productInfo;
+}

+ 68 - 0
src/main/java/com/caimei365/commodity/model/vo/ProductSalesVo.java

@@ -0,0 +1,68 @@
+package com.caimei365.commodity.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2021/10/11
+ */
+@Data
+public class ProductSalesVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private Integer id;
+    /**
+     * 商品ID
+     */
+    private Integer productId;
+    /**
+     * 商品名称
+     */
+    private String productName;
+    /**
+     * 供应商ID
+     */
+    private Integer shopId;
+    /**
+     * 供应商名称
+     */
+    private String shopName;
+    /**
+     * 销量
+     */
+    private Integer productCount;
+    /**
+     * 分类 ‘-’分割
+     */
+    private String property;
+    /**
+     * 商品属性:1产品,2仪器
+     */
+    private Integer commodityType;
+    /**
+     * 一级分类ID
+     */
+    private Integer bigTypeId;
+    /**
+     * 二级分类Id
+     */
+    private Integer smallTypeId;
+    /**
+     * 三级分类Id
+     */
+    private Integer tinyTypeId;
+
+    @Override
+    public String toString() {
+        return "ProductSalesVo{" +
+                "productId=" + productId +
+                ", productName='" + productName + '\'' +
+                ", shopName='" + shopName + '\'' +
+                ", productCount=" + productCount +
+                ", property='" + property + '\'' +
+                '}';
+    }
+}

+ 8 - 0
src/main/java/com/caimei365/commodity/service/PriceService.java

@@ -39,4 +39,12 @@ public interface PriceService {
      * @return LadderPriceVo
      * @return LadderPriceVo
      */
      */
     ResponseJson<List<LadderPriceVo>> getLadderPrice(Integer productId);
     ResponseJson<List<LadderPriceVo>> getLadderPrice(Integer productId);
+    /**
+     * 更新商品销量
+     * @param productInfo [ // 商品id,数量
+     *                   {"productId": 2789, "productCount": 1},
+     *                   {"productId": 2790, "productCount": 2}
+     *                 ]
+     */
+    ResponseJson<Void> productSaleUpdate(String productInfo);
 }
 }

+ 63 - 2
src/main/java/com/caimei365/commodity/service/impl/PriceServiceImpl.java

@@ -1,10 +1,13 @@
 package com.caimei365.commodity.service.impl;
 package com.caimei365.commodity.service.impl;
 
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.aliyun.opensearch.sdk.dependencies.com.google.common.collect.Lists;
 import com.aliyun.opensearch.sdk.dependencies.com.google.common.collect.Lists;
 import com.caimei365.commodity.components.PriceUtilService;
 import com.caimei365.commodity.components.PriceUtilService;
 import com.caimei365.commodity.mapper.PriceMapper;
 import com.caimei365.commodity.mapper.PriceMapper;
-import com.caimei365.commodity.mapper.PromotionsMapper;
+import com.caimei365.commodity.mapper.ShopMapper;
 import com.caimei365.commodity.model.ResponseJson;
 import com.caimei365.commodity.model.ResponseJson;
+import com.caimei365.commodity.model.vo.ProductSalesVo;
 import com.caimei365.commodity.model.vo.LadderPriceVo;
 import com.caimei365.commodity.model.vo.LadderPriceVo;
 import com.caimei365.commodity.model.vo.PriceVo;
 import com.caimei365.commodity.model.vo.PriceVo;
 import com.caimei365.commodity.model.vo.TaxVo;
 import com.caimei365.commodity.model.vo.TaxVo;
@@ -13,10 +16,14 @@ import com.caimei365.commodity.service.PriceService;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 import java.util.List;
 import java.util.List;
 
 
+import static com.alibaba.fastjson.JSON.parseArray;
+import static com.alibaba.fastjson.JSON.parseObject;
+
 /**
 /**
  * Description
  * Description
  *
  *
@@ -29,7 +36,7 @@ public class PriceServiceImpl implements PriceService {
     @Resource
     @Resource
     private PriceMapper priceMapper;
     private PriceMapper priceMapper;
     @Resource
     @Resource
-    private PromotionsMapper promotionsMapper;
+    private ShopMapper shopMapper;
     @Resource
     @Resource
     private PriceUtilService priceUtilService;
     private PriceUtilService priceUtilService;
     @Resource
     @Resource
@@ -100,4 +107,58 @@ public class PriceServiceImpl implements PriceService {
         }
         }
         return ResponseJson.success(ladderPrices);
         return ResponseJson.success(ladderPrices);
     }
     }
+
+    /**
+     * 更新商品销量
+     *
+     * @param productInfo [ // 商品id,数量
+     *                    {"productId": 2789, "productCount": 1},
+     *                    {"productId": 2790, "productCount": 2}
+     *                    ]
+     */
+    @Override
+    public ResponseJson<Void> productSaleUpdate(String productInfo) {
+        JSONArray infoArr = null;
+        try {
+            infoArr = parseArray(productInfo);
+        } catch (Exception e) {
+            log.error("【更新商品销量】商品信息解析异常try-catch:", e);
+            return ResponseJson.error("商品信息解析异常!", null);
+        }
+        if (null == infoArr) {
+            return ResponseJson.error("商品数据异常!", null);
+        }
+        // 遍历所有商品
+        for (Object productObject : infoArr) {
+            JSONObject productTemp = (JSONObject) productObject;
+            Integer productId = (Integer) productTemp.get("productId");
+            Integer productCount = (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);
+            // 获取供应商名称
+            String shopName = shopMapper.getShopNameByShopId(salesVo.getShopId());
+            salesVo.setShopName(shopName);
+            // 分类名称
+            String typeName = shopMapper.getTypeName(salesVo.getBigTypeId(), salesVo.getSmallTypeId(), salesVo.getTinyTypeId());
+            if (null != salesVo.getCommodityType() && 2 == salesVo.getCommodityType()){
+                salesVo.setProperty("仪器-"+typeName);
+            } else {
+                salesVo.setProperty("产品-"+typeName);
+            }
+            if (null == salesVo.getId()) {
+                // 新商品
+                priceMapper.insertProductSales(salesVo);
+            } else {
+                // 更新销量
+                priceMapper.updateProductSales(salesVo);
+            }
+            log.info("【更新商品销量】:"+salesVo.toString());
+        }
+        return ResponseJson.success(null);
+    }
 }
 }

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

@@ -109,4 +109,32 @@
           and userId = #{userId}
           and userId = #{userId}
     </select>
     </select>
 
 
+    <select id="getProductSalesInfo" resultType="com.caimei365.commodity.model.vo.ProductSalesVo">
+        select p.productID AS productId,
+               p.name AS productName,
+               p.shopID AS shopId,
+               p.commodityType,
+               p.bigTypeID as bigTypeId,
+               p.smallTypeID as smallTypeId,
+               p.tinyTypeID as tinyTypeId,
+               s.productId AS id,
+               s.shop AS shopName,
+               s.productCount AS productCount,
+               s.property AS property
+        FROM product p
+        LEFT JOIN cm_product_sales s ON p.productID = s.productId
+        where p.productId=#{productId}
+    </select>
+    <insert id="insertProductSales" parameterType="com.caimei365.commodity.model.vo.ProductSalesVo">
+        INSERT INTO cm_product_sales(productId, product, shop, productCount, property)
+        VALUES (#{productId}, #{productName}, #{shopName}, #{productCount}, #{property})
+    </insert>
+    <update id="updateProductSales" parameterType="com.caimei365.commodity.model.vo.ProductSalesVo">
+        UPDATE cm_product_sales
+        SET product=#{productName},
+            shop=#{shopName},
+            productCount=#{productCount},
+            property=#{property}
+        WHERE productId = #{productId}
+    </update>
 </mapper>
 </mapper>

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

@@ -94,7 +94,7 @@
     </select>
     </select>
     <select id="getProductListByPromotions" resultType="com.caimei365.commodity.model.search.ProductListVo">
     <select id="getProductListByPromotions" resultType="com.caimei365.commodity.model.search.ProductListVo">
 		select
 		select
-			p.productID as id,
+			p.productID as productId,
 			p.`name` as `name`,
 			p.`name` as `name`,
 			p.mainImage as image,
 			p.mainImage as image,
 			p.price1 as price,
 			p.price1 as price,

+ 3 - 0
src/main/resources/mapper/ShopMapper.xml

@@ -552,4 +552,7 @@
         select i.productId from new_page_floor_image i left join cm_page_centre c on i.centreId = c.id left join cm_page p on c.pageId = p.id
         select i.productId from new_page_floor_image i left join cm_page_centre c on i.centreId = c.id left join cm_page p on c.pageId = p.id
         where i.productId = #{productId} and i.appletsStatus = 1  and p.type = 7 and c.crmEnabledStatus = 1 and p.enabledStatus = 1 limit 1
         where i.productId = #{productId} and i.appletsStatus = 1  and p.type = 7 and c.crmEnabledStatus = 1 and p.enabledStatus = 1 limit 1
     </select>
     </select>
+    <select id="getShopNameByShopId" resultType="java.lang.String">
+        select name from shop where shopID = #{shopId}
+    </select>
 </mapper>
 </mapper>