1
0
lhm 3 gadi atpakaļ
vecāks
revīzija
abfd774880
44 mainītis faili ar 1634 papildinājumiem un 346 dzēšanām
  1. 1 1
      kmall-admin/pom.xml
  2. 9 1
      kmall-admin/src/main/java/com/kmall/admin/controller/OrderController.java
  3. 8 0
      kmall-admin/src/main/java/com/kmall/admin/dao/GoodsDao.java
  4. 17 0
      kmall-admin/src/main/java/com/kmall/admin/dao/MkActivitiesFullGiftDao.java
  5. 11 0
      kmall-admin/src/main/java/com/kmall/admin/dao/MkActivitiesPromotionDao.java
  6. 10 0
      kmall-admin/src/main/java/com/kmall/admin/dao/mk/MkActivitiesDao.java
  7. 50 0
      kmall-admin/src/main/java/com/kmall/admin/dto/GoodsDetailsDto.java
  8. 14 0
      kmall-admin/src/main/java/com/kmall/admin/entity/GoodsEntity.java
  9. 65 0
      kmall-admin/src/main/java/com/kmall/admin/entity/MkActivitiesCouponEntity.java
  10. 76 1
      kmall-admin/src/main/java/com/kmall/admin/entity/MkActivitiesFullGiftEntity.java
  11. 4 4
      kmall-admin/src/main/java/com/kmall/admin/haikong/client/HaiKongWarehouseTemplate.java
  12. 72 0
      kmall-admin/src/main/java/com/kmall/admin/haikong/constant/Constants.java
  13. 1 1
      kmall-admin/src/main/java/com/kmall/admin/haikong/dto/WareQueryStockResponseDTO.java
  14. 13 2
      kmall-admin/src/main/java/com/kmall/admin/haikong/task/MemberSysAccessTokenRefreshTask.java
  15. 37 0
      kmall-admin/src/main/java/com/kmall/admin/haikong/utils/Response.java
  16. 2 10
      kmall-admin/src/main/java/com/kmall/admin/haikong/utils/WareSysSignUtils.java
  17. 14 11
      kmall-admin/src/main/java/com/kmall/admin/haikong/utils/XmlUtils.java
  18. 20 6
      kmall-admin/src/main/java/com/kmall/admin/haikong/vo/QueryGoodsVo.java
  19. 8 0
      kmall-admin/src/main/java/com/kmall/admin/service/GoodsService.java
  20. 15 0
      kmall-admin/src/main/java/com/kmall/admin/service/MkActivitiesFullGiftService.java
  21. 8 0
      kmall-admin/src/main/java/com/kmall/admin/service/MkActivitiesPromotionService.java
  22. 9 0
      kmall-admin/src/main/java/com/kmall/admin/service/OrderService.java
  23. 306 248
      kmall-admin/src/main/java/com/kmall/admin/service/impl/GoodsServiceImpl.java
  24. 22 0
      kmall-admin/src/main/java/com/kmall/admin/service/impl/MkActivitiesFullGiftServiceImpl.java
  25. 12 0
      kmall-admin/src/main/java/com/kmall/admin/service/impl/MkActivitiesPromotionServiceImpl.java
  26. 404 25
      kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java
  27. 13 0
      kmall-admin/src/main/java/com/kmall/admin/service/impl/mk/MkActivitiesServiceImpl.java
  28. 9 0
      kmall-admin/src/main/java/com/kmall/admin/service/mk/MkActivitiesService.java
  29. 40 0
      kmall-admin/src/main/java/com/kmall/admin/vo/CalculateOrderDiscountPriceVo.java
  30. 10 3
      kmall-admin/src/main/resources/mybatis/mapper/GoodsDao.xml
  31. 46 6
      kmall-admin/src/main/resources/mybatis/mapper/MkActivitiesCouponDao.xml
  32. 116 7
      kmall-admin/src/main/resources/mybatis/mapper/MkActivitiesFullGiftDao.xml
  33. 21 1
      kmall-admin/src/main/resources/mybatis/mapper/MkActivitiesPromotionDao.xml
  34. 26 0
      kmall-admin/src/main/resources/mybatis/mapper/mk/MkActivitiesDao.xml
  35. 30 6
      kmall-admin/src/main/webapp/WEB-INF/page/mk/mkactivitiesfullgift.html
  36. 27 3
      kmall-admin/src/main/webapp/WEB-INF/page/sale/sale.html
  37. 10 4
      kmall-admin/src/main/webapp/js/mk/mkactivitiesfullgift.js
  38. 72 0
      kmall-admin/src/main/webapp/js/sale/sale.js
  39. 1 1
      kmall-api/pom.xml
  40. 1 1
      kmall-common/pom.xml
  41. 1 1
      kmall-framework/pom.xml
  42. 1 1
      kmall-gen/pom.xml
  43. 1 1
      kmall-manager/pom.xml
  44. 1 1
      kmall-schedule/pom.xml

+ 1 - 1
kmall-admin/pom.xml

@@ -3,7 +3,7 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <artifactId>kmall-pt-general</artifactId>
+        <artifactId>kmall-haikong</artifactId>
         <groupId>com.kmall</groupId>
         <version>3.1.0</version>
     </parent>

+ 9 - 1
kmall-admin/src/main/java/com/kmall/admin/controller/OrderController.java

@@ -1,13 +1,17 @@
 package com.kmall.admin.controller;
 
+import com.kmall.admin.dto.GoodsDetailsDto;
 import com.kmall.admin.dto.OrderExpressDto;
+import com.kmall.admin.dto.QueryOrderDto;
 import com.kmall.admin.dto.SystemFormatDto;
 import com.kmall.admin.entity.*;
 import com.kmall.admin.fromcomm.entity.SysUserEntity;
+import com.kmall.admin.haikong.vo.QueryGoodsVo;
 import com.kmall.admin.service.*;
 import com.kmall.admin.utils.CalculateTax;
 import com.kmall.admin.utils.ParamUtils;
 import com.kmall.admin.utils.ShiroUtils;
+import com.kmall.admin.vo.CalculateOrderDiscountPriceVo;
 import com.kmall.common.constant.Dict;
 import com.kmall.common.constant.JxlsXmlTemplateName;
 import com.kmall.common.utils.*;
@@ -1363,9 +1367,13 @@ public class OrderController {
 
     }
 
+    @PostMapping("/calculateOrderDiscountPrice")
+    public R calculateOrderDiscountPrice(@RequestBody CalculateOrderDiscountPriceVo calculateOrderDiscountPriceVo) {
 
+        List<GoodsDetailsDto> queryGoodsVos = orderService.calculateOrderDiscountPrice(calculateOrderDiscountPriceVo);
 
-
+        return R.ok().put("goodsList", queryGoodsVos);
+    }
 
 
 

+ 8 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/GoodsDao.java

@@ -114,4 +114,12 @@ public interface GoodsDao extends BaseDao<GoodsEntity> {
      * @return 商品信息
      */
     List<GoodsEntity> queryGoodsStockByQueryGoodsVoList(List<QueryGoodsVo> queryGoodsVoList);
+
+    /**
+     * 根据产品条码和sku查询保税展示补货的商品
+     * @param prodBarcode   商品条码
+     * @param sku           sku
+     * @return              商品信息
+     */
+    GoodsEntity queryGoodsInfoByProductBarcodeAndSku(@Param("prodBarcode") String prodBarcode, @Param("sku") String sku);
 }

+ 17 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/MkActivitiesFullGiftDao.java

@@ -5,6 +5,8 @@ import com.kmall.admin.entity.MkActivitiesFullGiftEntity;
 import com.kmall.manager.dao.BaseDao;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * 营销活动-满赠Dao
  *
@@ -26,4 +28,19 @@ public interface MkActivitiesFullGiftDao extends BaseDao<MkActivitiesFullGiftEnt
                                                   @Param("prodBarcode") String prodBarcode,
                                                   @Param("brandName") String brandName,
                                                   @Param("nowTime") String nowTime);
+
+    /**
+     * 根据营销活动编号获取满赠活动信息
+     * @param mkaIdList     营销活动编号集合
+     * @return              满赠营销活动信息
+     */
+    List<MkActivitiesFullGiftEntity> queryByMkaIdList(List<Long> mkaIdList);
+
+    /**
+     * 查询活动id对应的满赠活动规则
+     * @param mkaId 活动id
+     * @param storeId 门店id
+     * @return      满赠活动规则
+     */
+    MkActivitiesFullGiftEntity queryObjectByMkaIdAndStoreId(@Param("mkaId") Integer mkaId, @Param("storeId") String storeId);
 }

+ 11 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/MkActivitiesPromotionDao.java

@@ -5,6 +5,8 @@ import com.kmall.admin.entity.MkActivitiesPromotionEntity;
 import com.kmall.manager.dao.BaseDao;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * 营销活动-临时促销Dao
  *
@@ -31,4 +33,13 @@ public interface MkActivitiesPromotionDao extends BaseDao<MkActivitiesPromotionE
     void updatePriceBySku(@Param("updatePrice") String updatePrice,
                           @Param("sku") String sku,
                           @Param("mkaId") Long mkaId);
+
+    /**
+     * 查询活动id对应的限时特价活动规则
+     *
+     * @param mkaId   活动id
+     * @param storeId 门店id
+     * @return 限时特价活动规则
+     */
+    List<MkActivitiesPromotionEntity> queryListByMkaIdAndStoreId(@Param("mkaId") int mkaId, @Param("storeId") String storeId);
 }

+ 10 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/mk/MkActivitiesDao.java

@@ -24,4 +24,14 @@ public interface MkActivitiesDao extends BaseDao<MkActivitiesEntity> {
     List<MkActivitiesEntity> queryByNow(@Param("storeId") String storeId, @Param("currentTime") String currentTime);
 
     List<MkActivitiesEntity> queryByTopic(@Param("storeId") String storeId, @Param("currentTime")String currentTime, @Param("topic") String topic);
+
+    /**
+     * 根据门店id和当前时间查询有哪些营销方式
+     * 查询当前时间是否有满赠的活动
+     *
+     * @param storeId     门店id
+     * @param currentTime 当前时间
+     * @return 满赠活动列表
+     */
+    List<MkActivitiesEntity> queryByNowByMz(@Param("storeId") String storeId, @Param("currentTime") String currentTime);
 }

+ 50 - 0
kmall-admin/src/main/java/com/kmall/admin/dto/GoodsDetailsDto.java

@@ -64,6 +64,26 @@ public class GoodsDetailsDto {
     //商品库存
     private Integer goodsNumber;
 
+    /**
+     * 购物栏商品数量
+     */
+    private Integer sellVolume;
+
+    /**
+     * 购物栏商品下标
+     */
+    private Integer id;
+
+    /**
+     * 赠送数量
+     */
+    private Integer giftNumber;
+
+    /**
+     * 海控展销店出区数
+     */
+    private Integer exitRegionNumber;
+
     public BigDecimal getRmarketPrice() {
         return rmarketPrice;
     }
@@ -256,5 +276,35 @@ public class GoodsDetailsDto {
         this.ciqProdModel = ciqProdModel;
     }
 
+    public Integer getGiftNumber() {
+        return giftNumber;
+    }
+
+    public void setGiftNumber(Integer giftNumber) {
+        this.giftNumber = giftNumber;
+    }
+
+    public Integer getExitRegionNumber() {
+        return exitRegionNumber;
+    }
+
+    public void setExitRegionNumber(Integer exitRegionNumber) {
+        this.exitRegionNumber = exitRegionNumber;
+    }
 
+    public Integer getSellVolume() {
+        return sellVolume;
+    }
+
+    public void setSellVolume(Integer sellVolume) {
+        this.sellVolume = sellVolume;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
 }

+ 14 - 0
kmall-admin/src/main/java/com/kmall/admin/entity/GoodsEntity.java

@@ -274,11 +274,25 @@ public class GoodsEntity implements Serializable {
 
     private Integer toBeRestored;
 
+    /**
+     * 预估税
+     */
+    private BigDecimal goodsTaxes;
+
     public GoodsEntity() {
     }
 
     public GoodsEntity(QueryGoodsVo queryGoodsVo) {
         BeanUtils.copyProperties(this, queryGoodsVo);
+        this.goodsNumber = queryGoodsVo.getSellVolume();
+    }
+
+    public BigDecimal getGoodsTaxes() {
+        return goodsTaxes;
+    }
+
+    public void setGoodsTaxes(BigDecimal goodsTaxes) {
+        this.goodsTaxes = goodsTaxes;
     }
 
     public BigDecimal getCosmThresholdValue() {

+ 65 - 0
kmall-admin/src/main/java/com/kmall/admin/entity/MkActivitiesCouponEntity.java

@@ -65,6 +65,31 @@ public class MkActivitiesCouponEntity implements Serializable {
     private Date updateTime;
 
     /**
+     * 活动类别,0:按品牌 1:按商品分类 2:按商品
+     */
+    private String activityType;
+
+    /**
+     * 品牌id
+     */
+    private Integer brandId;
+
+    /**
+     * 品牌名称
+     */
+    private String brandName;
+
+    /**
+     * 分类id
+     */
+    private Integer categoryId;
+
+    /**
+     * 分类名称
+     */
+    private String categoryName;
+
+    /**
      * 设置:编号
      */
     public void setMacId(Long macId) {
@@ -220,4 +245,44 @@ public class MkActivitiesCouponEntity implements Serializable {
     public Date getUpdateTime() {
         return updateTime;
     }
+
+    public String getActivityType() {
+        return activityType;
+    }
+
+    public void setActivityType(String activityType) {
+        this.activityType = activityType;
+    }
+
+    public Integer getBrandId() {
+        return brandId;
+    }
+
+    public void setBrandId(Integer brandId) {
+        this.brandId = brandId;
+    }
+
+    public Integer getCategoryId() {
+        return categoryId;
+    }
+
+    public void setCategoryId(Integer categoryId) {
+        this.categoryId = categoryId;
+    }
+
+    public String getBrandName() {
+        return brandName;
+    }
+
+    public void setBrandName(String brandName) {
+        this.brandName = brandName;
+    }
+
+    public String getCategoryName() {
+        return categoryName;
+    }
+
+    public void setCategoryName(String categoryName) {
+        this.categoryName = categoryName;
+    }
 }

+ 76 - 1
kmall-admin/src/main/java/com/kmall/admin/entity/MkActivitiesFullGiftEntity.java

@@ -28,6 +28,10 @@ public class MkActivitiesFullGiftEntity implements Serializable {
      */
     private String shopSn;
     /**
+     * 门店名称
+     */
+    private String shopName;
+    /**
      * 商品编码
      */
     private String goodsSn;
@@ -36,6 +40,10 @@ public class MkActivitiesFullGiftEntity implements Serializable {
      */
     private String barcode;
     /**
+     * 商品品牌id
+     */
+    private Long brandId;
+    /**
      * 商品品牌
      */
     private String productBrand;
@@ -51,8 +59,26 @@ public class MkActivitiesFullGiftEntity implements Serializable {
      * 赠品条码
      */
     private String giftBarcode;
+    /**
+     * 赠品sku
+     */
     private String giftGoodsSn;
-
+    /**
+     * 赠品数量
+     */
+    private Integer giftNumber;
+    /**
+     * 满赠类型,0:按品牌 1:按分类
+     */
+    private String fullGiftType;
+    /**
+     * 商品分类id
+     */
+    private Long categoryId;
+    /**
+     * 商品分类名
+     */
+    private String categoryName;
     /**
      * 营销活动编号
      */
@@ -117,6 +143,15 @@ public class MkActivitiesFullGiftEntity implements Serializable {
     public String getShopSn() {
         return shopSn;
     }
+
+    public String getShopName() {
+        return shopName;
+    }
+
+    public void setShopName(String shopName) {
+        this.shopName = shopName;
+    }
+
     /**
      * 设置:商品编码
      */
@@ -281,4 +316,44 @@ public class MkActivitiesFullGiftEntity implements Serializable {
     public void setGiftGoodsSn(String giftGoodsSn) {
         this.giftGoodsSn = giftGoodsSn;
     }
+
+    public Long getBrandId() {
+        return brandId;
+    }
+
+    public void setBrandId(Long brandId) {
+        this.brandId = brandId;
+    }
+
+    public String getFullGiftType() {
+        return fullGiftType;
+    }
+
+    public void setFullGiftType(String fullGiftType) {
+        this.fullGiftType = fullGiftType;
+    }
+
+    public Long getCategoryId() {
+        return categoryId;
+    }
+
+    public void setCategoryId(Long categoryId) {
+        this.categoryId = categoryId;
+    }
+
+    public String getCategoryName() {
+        return categoryName;
+    }
+
+    public void setCategoryName(String categoryName) {
+        this.categoryName = categoryName;
+    }
+
+    public Integer getGiftNumber() {
+        return giftNumber;
+    }
+
+    public void setGiftNumber(Integer giftNumber) {
+        this.giftNumber = giftNumber;
+    }
 }

+ 4 - 4
kmall-admin/src/main/java/com/kmall/admin/haikong/client/HaiKongWarehouseTemplate.java

@@ -72,8 +72,8 @@ public class HaiKongWarehouseTemplate {
 
         criteria.setImperfectGrade("a");
         criteria.setInventoryType("SY");
-        criteria.setItemCode("test");
-        criteria.setItemId("SSS");
+        criteria.setItemCode("708177112730");
+//        criteria.setItemId("");
         criteria.setOwnerCode("44048600Y8");
         criteria.setWarehouseCode("20");
 
@@ -83,12 +83,12 @@ public class HaiKongWarehouseTemplate {
         criteria1.setImperfectGrade("a");
         criteria1.setInventoryType("SY");
         criteria1.setItemCode("test");
-        criteria1.setItemId("SSS");
+//        criteria1.setItemId("SSS");
         criteria1.setOwnerCode("44048600Y8");
         criteria1.setWarehouseCode("20");
 
         criteriaList.add(criteria);
-        criteriaList.add(criteria1);
+//        criteriaList.add(criteria1);
 
         wareQueryStockParamDTO.setCriteriaList(criteriaList);
 

+ 72 - 0
kmall-admin/src/main/java/com/kmall/admin/haikong/constant/Constants.java

@@ -12,4 +12,76 @@ public class Constants {
 
     public static final String MEMBER_SYS_REFRESH_TOKEN_REDIS_KEY = "haikong_memberSys_refreshToken";
 
+    /**
+     * 活动主题枚举
+     */
+    public enum ActivityTopicEnum {
+        /**
+         * 满赠活动
+         */
+        MZ("mz", "满赠"),
+        /**
+         * 限时特价活动
+         */
+        LSCX("lscx", "限时特价"),
+        /**
+         * 优惠券活动
+         */
+        YHJ("yhj", "优惠券")
+        ;
+
+        private final String topicCode;
+
+        private final String topicName;
+
+        ActivityTopicEnum(String topicCode, String topicName) {
+            this.topicCode = topicCode;
+            this.topicName = topicName;
+        }
+
+        public String getTopicCode() {
+            return topicCode;
+        }
+
+        public String getTopicName() {
+            return topicName;
+        }
+    }
+
+    /**
+     * 活动类型
+     */
+    public enum ActivityType {
+        /**
+         * 按品牌参加活动
+         */
+        BRAND("0", "商品品牌"),
+        /**
+         * 按分类参加活动
+         */
+        CATEGORY("1", "商品分类"),
+        /**
+         * 按单个商品参加活动
+         */
+        PRODUCT("2", "商品")
+        ;
+
+        private final String activityTypeCode;
+
+        private final String activityType;
+
+        ActivityType(String activityTypeCode, String activityType) {
+            this.activityTypeCode = activityTypeCode;
+            this.activityType = activityType;
+        }
+
+        public String getActivityTypeCode() {
+            return activityTypeCode;
+        }
+
+        public String getActivityType() {
+            return activityType;
+        }
+    }
+
 }

+ 1 - 1
kmall-admin/src/main/java/com/kmall/admin/haikong/dto/WareQueryStockResponseDTO.java

@@ -44,7 +44,7 @@ public class WareQueryStockResponseDTO implements Serializable {
      * 商品库存详细信息
      */
     @XmlAccessorType(XmlAccessType.FIELD)
-    private static class WareQueryStockResponseItemDTO {
+    public static class WareQueryStockResponseItemDTO {
 
         /**
          * 仓库编码

+ 13 - 2
kmall-admin/src/main/java/com/kmall/admin/haikong/task/MemberSysAccessTokenRefreshTask.java

@@ -14,6 +14,7 @@ import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
 
+import java.io.IOException;
 import java.util.Objects;
 import java.util.Optional;
 
@@ -58,14 +59,24 @@ public class MemberSysAccessTokenRefreshTask {
     }
 
     private void handleResponse(String json, Boolean a) {
-        Response<AccessTokenDTO> response = JacksonUtil.fromListJson(json, new TypeReference<Response<AccessTokenDTO>>() {
-        });
+        Response<AccessTokenDTO> response = null;
+        try {
+            response = JacksonUtil.getObjectMapper().readValue(json, new TypeReference<Response<AccessTokenDTO>>() {
+            });
+        } catch (IOException e) {
+            log.error("解析海控会员系统响应结果失败!", e);
+            return;
+        }
         if (Objects.nonNull(response) && response.getSuccess()) {
             AccessTokenDTO accessTokenDTO = response.getData();
             JedisUtil.set(Constants.MEMBER_SYS_ACCESS_TOKEN_REDIS_KEY, JacksonUtil.toJson(accessTokenDTO), (60 * 60 * 2) - (60 * 2));
             if (a) {
                 JedisUtil.set(Constants.MEMBER_SYS_REFRESH_TOKEN_REDIS_KEY, Optional.ofNullable(accessTokenDTO.getRefreshToken()).orElse(""), (60 * 60 * 24 * 7));
             }
+        } else if (Objects.nonNull(response) && !response.getSuccess() && Response.ErrorCodeEnum.INVALID_REFRESH.getErrorCode().equals(response.getErrorCode())) {
+            log.info("海控会员系统RefreshToken已失效,重新获取AccessToken与RefreshToken!");
+            JedisUtil.del(Constants.MEMBER_SYS_REFRESH_TOKEN_REDIS_KEY);
+            refresh();
         } else {
             log.error("请求海控会员系统AccessToken返回响应为空!");
         }

+ 37 - 0
kmall-admin/src/main/java/com/kmall/admin/haikong/utils/Response.java

@@ -1,5 +1,7 @@
 package com.kmall.admin.haikong.utils;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 /**
  * 通用响应处理, 对接海控
  * @author lhm
@@ -9,8 +11,10 @@ public class Response<T> {
 
     private Boolean success;
 
+    @JsonProperty("error_code")
     private Integer errorCode;
 
+    @JsonProperty("error_message")
     private String errorMessage;
 
     private T data;
@@ -89,4 +93,37 @@ public class Response<T> {
                 ", totalCount=" + totalCount +
                 '}';
     }
+
+    /**
+     * 错误响应码枚举
+     */
+    public enum ErrorCodeEnum {
+        /**
+         * 无效的refresh_token
+         */
+        INVALID_REFRESH(1005, "无效的refresh_token");
+
+        /**
+         * 错误码
+         */
+        private final Integer errorCode;
+
+        /**
+         * 错误消息
+         */
+        private final String errorMessage;
+
+        ErrorCodeEnum(Integer errorCode, String errorMessage) {
+            this.errorCode = errorCode;
+            this.errorMessage = errorMessage;
+        }
+
+        public Integer getErrorCode() {
+            return errorCode;
+        }
+
+        public String getErrorMessage() {
+            return errorMessage;
+        }
+    }
 }

+ 2 - 10
kmall-admin/src/main/java/com/kmall/admin/haikong/utils/WareSysSignUtils.java

@@ -4,6 +4,7 @@ import cn.hutool.core.map.MapUtil;
 import org.apache.commons.lang.StringUtils;
 
 import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
 import java.util.Arrays;
@@ -39,16 +40,7 @@ public class WareSysSignUtils {
 
     public static String getSignRequest(String url, String body, String secretKey) throws Exception {
         String sign = signRequest(formatUrl(url), body, secretKey);
-        Map<String, String> formatUrl = formatUrl(url);
-        StringBuilder head = new StringBuilder(url.substring(0, url.indexOf("?")));
-        formatUrl.keySet().forEach(key -> {
-            formatUrl.put(key, java.net.URLEncoder.encode(new String(formatUrl.get(key).getBytes(StandardCharsets.UTF_8))));
-            head.append("&").append(key).append("=").append(formatUrl.get(key));
-        });
-        String s = head.toString();
-        String substring = s.substring(0, s.indexOf("&"));
-        String substring1 = s.substring(s.indexOf("&") + 1);
-        return substring + "?" + substring1 + "&sign=" + sign;
+        return url + "&sign=" + sign;
     }
 
 

+ 14 - 11
kmall-admin/src/main/java/com/kmall/admin/haikong/utils/XmlUtils.java

@@ -8,6 +8,7 @@ import javax.xml.bind.Unmarshaller;
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.util.Objects;
 
 /**
  * @author lhm
@@ -41,7 +42,7 @@ public class XmlUtils {
             marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
 
             StringWriter writer = new StringWriter();
-            writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+            writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
             marshaller.marshal(obj, writer);
             return writer.toString();
         } catch (Exception e) {
@@ -57,20 +58,22 @@ public class XmlUtils {
      * @return
      */
     public static <T> Object toObject(String xml, Class<T> c) throws Exception {
-        Object xmlObject = null;
         Reader reader = null;
-        JAXBContext context = JAXBContext.newInstance(c);
-        // XML 转为对象的接口
-        Unmarshaller unmarshaller = context.createUnmarshaller();
+        try {
+            JAXBContext context = JAXBContext.newInstance(c);
+            // XML 转为对象的接口
+            Unmarshaller unmarshaller = context.createUnmarshaller();
 
-        reader = new StringReader(xml);
-        xmlObject = unmarshaller.unmarshal(reader);
+            reader = new StringReader(xml);
 
-        if (null != reader) {
-            reader.close();
+            return unmarshaller.unmarshal(reader);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (Objects.nonNull(reader)) {
+                reader.close();
+            }
         }
-
-        return xmlObject;
     }
 
 

+ 20 - 6
kmall-admin/src/main/java/com/kmall/admin/haikong/vo/QueryGoodsVo.java

@@ -38,7 +38,7 @@ public class QueryGoodsVo {
     /**
      * 商品预估税
      */
-    private BigDecimal goodstaxes;
+    private BigDecimal goodsTaxes;
 
     /**
      * 商品优惠金额
@@ -120,6 +120,11 @@ public class QueryGoodsVo {
      */
     private Integer exitRegionNumber;
 
+    /**
+     * 总价格,含税价
+     */
+    private BigDecimal totalPrice;
+
     public String getProdBarcode() {
         return prodBarcode;
     }
@@ -160,12 +165,12 @@ public class QueryGoodsVo {
         this.retailPrice = retailPrice;
     }
 
-    public BigDecimal getGoodstaxes() {
-        return goodstaxes;
+    public BigDecimal getGoodsTaxes() {
+        return goodsTaxes;
     }
 
-    public void setGoodstaxes(BigDecimal goodstaxes) {
-        this.goodstaxes = goodstaxes;
+    public void setGoodsTaxes(BigDecimal goodsTaxes) {
+        this.goodsTaxes = goodsTaxes;
     }
 
     public BigDecimal getDisCountedPrice() {
@@ -296,6 +301,14 @@ public class QueryGoodsVo {
         this.exitRegionNumber = exitRegionNumber;
     }
 
+    public BigDecimal getTotalPrice() {
+        return totalPrice;
+    }
+
+    public void setTotalPrice(BigDecimal totalPrice) {
+        this.totalPrice = totalPrice;
+    }
+
     @Override
     public String toString() {
         return "QueryGoodsVo{" +
@@ -304,7 +317,7 @@ public class QueryGoodsVo {
                 ", storeId=" + storeId +
                 ", sellVolume=" + sellVolume +
                 ", retailPrice=" + retailPrice +
-                ", goodstaxes=" + goodstaxes +
+                ", goodsTaxes=" + goodsTaxes +
                 ", disCountedPrice=" + disCountedPrice +
                 ", goodsNumber=" + goodsNumber +
                 ", goodsSn='" + goodsSn + '\'' +
@@ -321,6 +334,7 @@ public class QueryGoodsVo {
                 ", ciqProdModel='" + ciqProdModel + '\'' +
                 ", toBeRestored=" + toBeRestored +
                 ", exitRegionNumber=" + exitRegionNumber +
+                ", totalPrice=" + totalPrice +
                 '}';
     }
 

+ 8 - 0
kmall-admin/src/main/java/com/kmall/admin/service/GoodsService.java

@@ -235,4 +235,12 @@ public interface GoodsService {
      * @return              商品信息
      */
     List<GoodsEntity> queryGoodsStockByQueryGoodsVoList(List<QueryGoodsVo> queryGoodsVoList);
+
+    /**
+     * 根据产品条码和sku查询保税展示补货的商品
+     * @param prodBarcode   商品条码
+     * @param sku           sku
+     * @return              商品信息
+     */
+    GoodsEntity queryGoodsInfoByProductBarcodeAndSku(String prodBarcode, String sku);
 }

+ 15 - 0
kmall-admin/src/main/java/com/kmall/admin/service/MkActivitiesFullGiftService.java

@@ -89,4 +89,19 @@ public interface MkActivitiesFullGiftService {
      * @return
      */
     MkActivitiesFullGiftEntity queryByCodeOrBrand(String mkaId, String prodBarcode, String brandName, String nowTime);
+
+    /**
+     * 根据营销活动编号获取满赠活动信息
+     * @param mkaIdList     营销活动编号集合
+     * @return              满赠营销活动信息
+     */
+    List<MkActivitiesFullGiftEntity> queryByMkaIdList(List<Long> mkaIdList);
+
+    /**
+     * 查询活动id对应的满赠活动规则
+     * @param mkaId 活动id
+     * @param storeId 门店id
+     * @return      满赠活动规则
+     */
+    MkActivitiesFullGiftEntity queryObjectByMkaIdAndStoreId(Integer mkaId, String storeId);
 }

+ 8 - 0
kmall-admin/src/main/java/com/kmall/admin/service/MkActivitiesPromotionService.java

@@ -104,4 +104,12 @@ public interface MkActivitiesPromotionService {
      * @param mkaId
      */
     void updatePriceBySku(String updatePrice, String sku, Long mkaId);
+
+    /**
+     * 查询活动id对应的限时特价活动规则
+     * @param mkaId 活动id
+     * @param storeId 门店id
+     * @return      限时特价活动规则
+     */
+    List<MkActivitiesPromotionEntity> queryListByMkaIdAndStoreId(int mkaId, String storeId);
 }

+ 9 - 0
kmall-admin/src/main/java/com/kmall/admin/service/OrderService.java

@@ -3,6 +3,8 @@ package com.kmall.admin.service;
 import com.kmall.admin.dto.*;
 import com.kmall.admin.entity.*;
 import com.kmall.admin.fromcomm.entity.SysUserEntity;
+import com.kmall.admin.haikong.vo.QueryGoodsVo;
+import com.kmall.admin.vo.CalculateOrderDiscountPriceVo;
 import com.kmall.common.utils.Query;
 import com.kmall.common.utils.R;
 import com.kmall.manager.manager.alipay.AliPayMicropayApiResult;
@@ -234,4 +236,11 @@ public interface OrderService {
     void toBeRestored(String orderSn);
 
     Ticket printMsgEwb(long longValue, String sessionId);
+
+    /**
+     * 计算优惠价格,活动价格
+     * @param calculateOrderDiscountPriceVo 请求参数
+     * @return  商品集合
+     */
+    List<GoodsDetailsDto> calculateOrderDiscountPrice(CalculateOrderDiscountPriceVo calculateOrderDiscountPriceVo);
 }

+ 306 - 248
kmall-admin/src/main/java/com/kmall/admin/service/impl/GoodsServiceImpl.java

@@ -13,6 +13,10 @@ import com.kmall.admin.entity.*;
 import com.kmall.admin.entity.kmall2eccs.KtoEccsEntity;
 import com.kmall.admin.entity.mk.MkActivitiesEntity;
 import com.kmall.admin.entity.shop.ShopErrorPriceRecordEntity;
+import com.kmall.admin.haikong.client.HaiKongWarehouseTemplate;
+import com.kmall.admin.haikong.dto.Criteria;
+import com.kmall.admin.haikong.dto.WareQueryStockParamDTO;
+import com.kmall.admin.haikong.dto.WareQueryStockResponseDTO;
 import com.kmall.admin.haikong.vo.QueryGoodsVo;
 import com.kmall.admin.service.*;
 import com.kmall.admin.service.kmall2eccs.KtoEccsService;
@@ -23,11 +27,15 @@ import com.kmall.admin.service.shop.ShopErrorPriceRecordService;
 import com.kmall.admin.utils.CalculateTax;
 import com.kmall.admin.utils.GoodsUtils;
 import com.kmall.admin.utils.ShiroUtils;
+import com.kmall.admin.utils.jackson.JacksonUtil;
 import com.kmall.api.entity.exportpdf.PDFGoodsDto;
 import com.kmall.common.constant.Dict;
 import com.kmall.admin.fromcomm.entity.SysUserEntity;
 import com.kmall.common.utils.*;
+import com.kmall.manager.manager.express.sf.ServiceException;
 import com.kmall.manager.manager.redis.JedisUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -36,6 +44,7 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 /**
@@ -47,6 +56,9 @@ import java.util.stream.Collectors;
  */
 @Service("goodsService")
 public class GoodsServiceImpl implements GoodsService {
+
+    private static final Logger log = LoggerFactory.getLogger(GoodsServiceImpl.class);
+
     @Autowired
     private MerchDao merchDao;
     @Autowired
@@ -120,6 +132,9 @@ public class GoodsServiceImpl implements GoodsService {
     @Autowired
     private KtoEccsService ktoEccsService;
 
+    @Autowired
+    private HaiKongWarehouseTemplate haiKongWarehouseTemplate;
+
     @Override
     public GoodsEntity queryObject(Integer id) {
         Map<String, Object> map = new HashMap<String, Object>();
@@ -1733,7 +1748,7 @@ public class GoodsServiceImpl implements GoodsService {
 
     /**
      * 查询产品价格
-     *
+     * 改进后的逻辑:
      * @param prodBarcode
      * @param storeId
      * @return
@@ -1748,264 +1763,297 @@ public class GoodsServiceImpl implements GoodsService {
         if(goods == null) {
             return null;
         }
+
+        /*
+        * 2. 查询海仓仓库系统,判断库存是否足够
+        * */
+        /*WareQueryStockParamDTO wareQueryStockParamDTO = new WareQueryStockParamDTO();
+        List<Criteria> criteriaList = new ArrayList<>();
+        Criteria criteria = new Criteria();
+        criteria.setItemId(goods.getProdBarcode());
+        criteria.setItemCode(goods.getSku());
+        criteriaList.add(criteria);
+        wareQueryStockParamDTO.setCriteriaList(criteriaList);
+        String queryWarehouseStockResponse = haiKongWarehouseTemplate.queryWarehouseStock(wareQueryStockParamDTO);
+        log.info("调用海控仓库系统,请求参数,门店:{}、商品条码:{}、商品编码:{},响应数据:{}", storeId, prodBarcode, sku, queryWarehouseStockResponse);
+        if (org.springframework.util.StringUtils.isEmpty(queryWarehouseStockResponse)) {
+            log.error("调用库存系统接口出现错误!返回结果为空!");
+            throw new ServiceException("调用库存系统接口出现错误!");
+        }
+        WareQueryStockResponseDTO wareQueryStockResponseDTO = JacksonUtil.fromStringJson(queryWarehouseStockResponse, WareQueryStockResponseDTO.class);
+        if (Objects.isNull(wareQueryStockResponseDTO)) {
+            log.error("解析一步达库存系统响应数据出现错误!请求响应结果:{}", queryWarehouseStockResponse);
+            throw new ServiceException("解析一步达库存系统响应数据出现错误!");
+        }
+        // 校验库存
+        WareQueryStockResponseDTO.WareQueryStockResponseItemDTO itemDTO = wareQueryStockResponseDTO.getItems().get(0);
+        // 仓库可用库存
+        int wareQuantity = itemDTO.getQuantity() - itemDTO.getLockQuantity();
+        // 海控展销店出区数
+        Integer exitRegionNumber = goods.getExitRegionNumber();
+        // 门店库存
+        String stockNum = goods.getStockNum();
+        // 扫码只会扫一件商品,保税仓库存 + 展销店库存 - 出区数 >= 购买数
+        if (!((wareQuantity + Integer.parseInt(stockNum) - exitRegionNumber) >= 1)) {
+            // 库存不足
+            log.error("商品条码:【{}】,sku:【{}】,门店ID:【{}】,该商品库存不足!", prodBarcode, sku, storeId);
+            throw new ServiceException(String.format("商品条码:【%s】,sku:【%s】,门店ID:【%s】,该商品库存不足!", prodBarcode, sku, storeId));
+        }*/
         goods.setDiscountedPrice(new BigDecimal(0));
         BigDecimal retailPrice = goods.getRetailPrice();
 
-
         goods.setActualPaymentAmount(retailPrice.setScale(2,RoundingMode.HALF_UP));
 
         Map<String,Object> skuActivitiesMap = new HashMap<>();
 
-        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-
-        /**
-         * 2.查询当前时间,该门店是否有活动,如果有活动,查询开启了哪些营销方式
-         * 参数: 当前时间  门店id
-         */
-        List<MkActivitiesEntity> mkActivitiesEntityList = mkActivitiesService.queryByNow(storeId,format.format(new Date()));
-
-        if(mkActivitiesEntityList == null || mkActivitiesEntityList.size() == 0){
-            // 计算税费
-            GoodsEntity goodsEntity = goodsDao.queryByBarcodeAndSku(prodBarcode, goods.getGoodsSn());
-            BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity,goods.getActualPaymentAmount(),this).setScale(3,RoundingMode.HALF_UP);
-            goods.setGoodstaxes(tax.toString());
-            skuActivitiesMap.put("goods",goods);
-            return skuActivitiesMap;
-        }
-
-
-
-        // 遍历活动集合,查询有哪些活动是开启的
-        boolean daily = false,coupon = false,combinationPrice = false
-                ,discount = false,fullGift = false,fullReduction = false
-                ,getOneFree = false,promotion = false,halfPrice = false;
-
-        List<String> topicList = new ArrayList<>(); // 记录有哪些营销活动的topic
-        Map<String,String> mkaIdMap = new HashMap<>(); // 记录topic跟mkaId的关系
-        // 将所有的营销活动新增到list中
-        for(MkActivitiesEntity mkActivitiesEntity : mkActivitiesEntityList){
-            topicList.add(mkActivitiesEntity.getMkaTopic());
-            String mkaId = mkaIdMap.putIfAbsent(mkActivitiesEntity.getMkaTopic(), mkActivitiesEntity.getMkaId()+"");
-            if(StringUtils.isNotEmpty(mkaId)){
-//                mkaId = "'"+mkaId + "','" + mkActivitiesEntity.getMkaId()+"'";
-                mkaId += String.format(",%s",mkActivitiesEntity.getMkaId());
-                mkaIdMap.put(mkActivitiesEntity.getMkaTopic(),mkaId);
-            }
-        }
-        // 判断有哪些营销活动
-        if(topicList.contains("zhjsp")) // 组合价
-            combinationPrice = true;
-        if(topicList.contains("dz")) // 打折
-            discount = true;
-        if(topicList.contains("mz")) //满赠
-            fullGift = true;
-        if(topicList.contains("mj"))  // 满减
-            fullReduction = true;
-        if(topicList.contains("mysy")) // 买一送一
-            getOneFree = true;
-        if(topicList.contains("rchd")) // 日常活动
-            daily = true;
-        if(topicList.contains("yhq")) // 优惠券
-            coupon = true;
-        if(topicList.contains("lscx")) // 临时促销
-            promotion = true;
-        if(topicList.contains("drjbj"))
-            halfPrice = true;
-
-
-        // 获取未优惠前的商品价格
-        retailPrice = goods.getRetailPrice();
-
-
-        // 根据条码查询商品品牌名称 mall_brand  mall_product_store_rela  mall_goods
-        String brandName = goods.getBrand();
-
-        /**
-         * 优先级:临时促销 》买一送一=满赠 》 组合价=日常活动 》 打折=满减 》 优惠券
-         */
-
-        /**
-         * 组合价的做法就是将参与组合的条码带到收银端
-         * 现根据营销活动id跟条形码,查询有哪些参与该条码组合的商品
-         *
-         *
-         * TODO
-         */
-        if(combinationPrice){
-            String mkaId = mkaIdMap.get("zhjsp");
-            Map<String,Object> param = new HashMap<>();
-            param.put("mkaId",mkaId);
-            param.put("prodBarcode",prodBarcode);
-            List<MkActivitiesCombinationPriceEntity> combinationPriceList = combinationPriceService.queryList(param);
-            if(combinationPriceList != null && combinationPriceList.size() > 0) {
-                Map<String, List<MkActivitiesCombinationPriceEntity>> collect =
-                        combinationPriceList.stream().collect(Collectors.groupingBy(MkActivitiesCombinationPriceEntity::getCombinationType));
-
-                skuActivitiesMap.put("zhjsp",collect);
-            }
-        }
-
-
-
-        format = new SimpleDateFormat("yyyy-MM-dd");
-        String nowTime = format.format(new Date());
-        /**
-         * 满减可能是跟着条码,也可能跟着品牌
-         * 根据商品品牌跟商品条码去查询是否有优惠金额
-         *
-         * 满足金额   购买商品条码   赠品条码
-         *
-         */
-        Map<String,Object> fullReductionMap = new HashMap<>();
-        if(fullReduction){
-            String mkaId = mkaIdMap.get("mj");
-            MkActivitiesFullReductionEntity fullReductionEntity = fullReductionService.queryByCodeOrBrand(mkaId,prodBarcode,brandName,nowTime);
-            if(fullReductionEntity != null) {
-                if(!StringUtils.isNullOrEmpty(fullReductionEntity.getProductBrand())){
-                    // 跟着品牌走
-                    fullReductionMap.put(brandName,fullReductionEntity);
-                }else{
-                    // 跟着条码走
-                    fullReductionMap.put(fullReductionEntity.getBarcode(), fullReductionEntity);
-                }
-                skuActivitiesMap.put("mj",fullReductionMap);
-            }
-        }
-
-        /**
-         * 满赠可能是跟着条码,也可能跟着品牌
-         * 根据商品品牌跟商品条码去查询是否有满赠
-         * 1.先扫买的商品,然后查询出赠送的商品条码
-         * 2.先扫赠的商品,然后查询出符合条件的商品条码或者品牌
-         * 满足的金额   购买的商品条码或者品牌   赠送的商品条码
-         * TODO
-         */
-        Map<String,Object> fullGiftMap = new HashMap<>();
-        if(fullGift){
-            String mkaId = mkaIdMap.get("mz");
-            MkActivitiesFullGiftEntity giftEntity = fullGiftService.queryByCodeOrBrand(mkaId,prodBarcode,brandName,nowTime);
-            if(giftEntity != null) {
-                if(giftEntity.getProductBrand() != null){
-                    // 跟着品牌走
-                    fullGiftMap.put(brandName,giftEntity);
-                }else{
-                    // 跟着条码走
-                    fullGiftMap.put(giftEntity.getBarcode(), giftEntity);
-                }
-                skuActivitiesMap.put("mz",fullGiftMap);
-            }
-        }
-
-        /**
-         * 买一送一可能是跟着条码,也可能跟着品牌
-         * 根据商品品牌跟商品条码去查询是否有送的商品
-         * 有两个场景
-         * 1.先扫买的商品,然后查询出赠送的商品条码
-         * 2.先扫赠的商品,然后查询出符合条件的商品条码或者品牌
-         * 所以就需要一个map
-         * key为购买的商品条码或者商品品牌  value为赠送的商品条码
-         * 但是品牌是根据条码查询的,所以最终map里面的结构是
-         * key 商品条码 value 赠品条码
-         */
-        if(getOneFree){
-            String mkaId = mkaIdMap.get("mysy");
-            MkActivitiesGetOneFreeGoodsEntity getOneFreeGoodsEntity = getOneFreeGoodsService.queryByCodeOrBrand(mkaId,prodBarcode,brandName);
-            if(getOneFreeGoodsEntity != null){
-                if("无".equals(getOneFreeGoodsEntity.getProductBrand())){
-                    getOneFreeGoodsEntity.setBrand(false);
-                    skuActivitiesMap.put("mysy",getOneFreeGoodsEntity);
-                }else{
-                    getOneFreeGoodsEntity.setBrand(true);
-                    skuActivitiesMap.put("mysy",getOneFreeGoodsEntity);
-                }
-
-            }
-        }
-
-
-        // 第二份半价
-        if(halfPrice){
-            String mkaId = mkaIdMap.get("drjbj");
-            MkActivitiesHalfPriceEntity activitiesHalfPriceEntity = halfPriceService.queryByCodeOrBrand(mkaId,prodBarcode);
-            if(activitiesHalfPriceEntity != null){
-                skuActivitiesMap.put("drjbj",activitiesHalfPriceEntity);
-
-            }
-
-        }
-
-
-        // --------------------------------------------------------------------------------------
-
-        /**
-         * 优惠券跟着条形码走,一般是设置一个标识,然后最后输入优惠券码后,减扣对应的标识,所以返回一个map数组
-         */
-
-        if(coupon){
-            String mkaId = mkaIdMap.get("yhq");
-            MkActivitiesCouponEntity couponEntity =  couponService.queryByBarCode(mkaId,prodBarcode,nowTime);
-            if(couponEntity != null){ // 优惠券码,优惠金额
-                Map<String,Object> returnMap = new HashMap<>();
-                returnMap.put(couponEntity.getCouponSn() , couponEntity.getCouponPrice());
-                skuActivitiesMap.put("yhq",returnMap);
-            }
-        }
-
-
-        /**
-         * 打折的价格是与条形码对应的,所以需要根据条形码和营销方式id去查询活动价格
-         */
-
-        if(discount){
-            String mkaId = mkaIdMap.get("dz");
-            MkActivitiesDiscountEntity discountEntity =  discountService.queryByBarCode(mkaId,prodBarcode);
-            // TODO 可能会直接替代产品价格
-            if (discountEntity != null) {
-                goods.setActualPaymentAmount(discountEntity.getActivityPrice());
-                goods.setRetailPrice(discountEntity.getActivityPrice());
-
-                goods.setActivity("打折");
-            }
-        }
-
-
-        /**
-         * 日常活动跟着条形码走,优先级比临时促销低,但是高于正常价格
-         */
-        if(daily){
-            String mkaId = mkaIdMap.get("rchd");
-            MkDailyActivitiesEntity dailyActivitiesEntity = dailyActivitiesService.queryByBarCode(mkaId,prodBarcode);
-            if(dailyActivitiesEntity != null){
-                goods.setActualPaymentAmount(dailyActivitiesEntity.getActivityPrice());
-                goods.setRetailPrice(dailyActivitiesEntity.getActivityPrice());
-
-                goods.setActivity("日常活动");
-
-            }
-        }
-
-
-        /**
-         * 临时促销跟着条形码走,优先级应该最高,所以排到了最下面
-         */
-        if(promotion){
-            String mkaId = mkaIdMap.get("lscx");
-            MkActivitiesPromotionEntity promotionEntity = promotionService.queryByBarCode(mkaId,prodBarcode);
-            // 如果该商品存在临时促销,直接替换活动价格
-            if(promotionEntity != null){
-                goods.setActualPaymentAmount(promotionEntity.getActivityPrice());
-                goods.setRetailPrice(promotionEntity.getActivityPrice());
-
-                goods.setActivity("临时促销");
-
-            }
-        }
+//        /**
+//         * 2.查询当前时间,该门店是否有活动,如果有活动,查询开启了哪些营销方式
+//         * 参数: 当前时间  门店id
+//         */
+//        /*List<MkActivitiesEntity> mkActivitiesEntityList = mkActivitiesService.queryByNow(storeId,format.format(new Date()));
+//
+//        if(mkActivitiesEntityList == null || mkActivitiesEntityList.size() == 0){
+//            // 计算税费
+//            GoodsEntity goodsEntity = goodsDao.queryByBarcodeAndSku(prodBarcode, goods.getGoodsSn());
+//            BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity,goods.getActualPaymentAmount(),this).setScale(3,RoundingMode.HALF_UP);
+//            goods.setGoodstaxes(tax.toString());
+//            skuActivitiesMap.put("goods",goods);
+//            return skuActivitiesMap;
+//        }
+//
+//
+//
+//        // 遍历活动集合,查询有哪些活动是开启的
+//        boolean daily = false,coupon = false,combinationPrice = false
+//                ,discount = false,fullGift = false,fullReduction = false
+//                ,getOneFree = false,promotion = false,halfPrice = false;
+//
+//        List<String> topicList = new ArrayList<>(); // 记录有哪些营销活动的topic
+//        Map<String,String> mkaIdMap = new HashMap<>(); // 记录topic跟mkaId的关系
+//        // 将所有的营销活动新增到list中
+//        for(MkActivitiesEntity mkActivitiesEntity : mkActivitiesEntityList){
+//            topicList.add(mkActivitiesEntity.getMkaTopic());
+//            String mkaId = mkaIdMap.putIfAbsent(mkActivitiesEntity.getMkaTopic(), mkActivitiesEntity.getMkaId()+"");
+//            if(StringUtils.isNotEmpty(mkaId)){
+////                mkaId = "'"+mkaId + "','" + mkActivitiesEntity.getMkaId()+"'";
+//                mkaId += String.format(",%s",mkActivitiesEntity.getMkaId());
+//                mkaIdMap.put(mkActivitiesEntity.getMkaTopic(),mkaId);
+//            }
+//        }
+//        // 判断有哪些营销活动
+//        if(topicList.contains("zhjsp")) // 组合价
+//            combinationPrice = true;
+//        if(topicList.contains("dz")) // 打折
+//            discount = true;
+//        if(topicList.contains("mz")) //满赠
+//            fullGift = true;
+//        if(topicList.contains("mj"))  // 满减
+//            fullReduction = true;
+//        if(topicList.contains("mysy")) // 买一送一
+//            getOneFree = true;
+//        if(topicList.contains("rchd")) // 日常活动
+//            daily = true;
+//        if(topicList.contains("yhq")) // 优惠券
+//            coupon = true;
+//        if(topicList.contains("lscx")) // 临时促销
+//            promotion = true;
+//        if(topicList.contains("drjbj"))
+//            halfPrice = true;
+//
+//
+//        // 获取未优惠前的商品价格
+//        retailPrice = goods.getRetailPrice();
+//
+//
+//        // 根据条码查询商品品牌名称 mall_brand  mall_product_store_rela  mall_goods
+//        String brandName = goods.getBrand();
+//
+//        *//**
+//         * 优先级:临时促销 》买一送一=满赠 》 组合价=日常活动 》 打折=满减 》 优惠券
+//         *//*
+//
+//        *//**
+//         * 组合价的做法就是将参与组合的条码带到收银端
+//         * 现根据营销活动id跟条形码,查询有哪些参与该条码组合的商品
+//         *
+//         *
+//         * TODO
+//         *//*
+//        if(combinationPrice){
+//            String mkaId = mkaIdMap.get("zhjsp");
+//            Map<String,Object> param = new HashMap<>();
+//            param.put("mkaId",mkaId);
+//            param.put("prodBarcode",prodBarcode);
+//            List<MkActivitiesCombinationPriceEntity> combinationPriceList = combinationPriceService.queryList(param);
+//            if(combinationPriceList != null && combinationPriceList.size() > 0) {
+//                Map<String, List<MkActivitiesCombinationPriceEntity>> collect =
+//                        combinationPriceList.stream().collect(Collectors.groupingBy(MkActivitiesCombinationPriceEntity::getCombinationType));
+//
+//                skuActivitiesMap.put("zhjsp",collect);
+//            }
+//        }
+//
+//
+//
+//        format = new SimpleDateFormat("yyyy-MM-dd");
+//        String nowTime = format.format(new Date());
+//        *//**
+//         * 满减可能是跟着条码,也可能跟着品牌
+//         * 根据商品品牌跟商品条码去查询是否有优惠金额
+//         *
+//         * 满足金额   购买商品条码   赠品条码
+//         *
+//         *//*
+//        Map<String,Object> fullReductionMap = new HashMap<>();
+//        if(fullReduction){
+//            String mkaId = mkaIdMap.get("mj");
+//            MkActivitiesFullReductionEntity fullReductionEntity = fullReductionService.queryByCodeOrBrand(mkaId,prodBarcode,brandName,nowTime);
+//            if(fullReductionEntity != null) {
+//                if(!StringUtils.isNullOrEmpty(fullReductionEntity.getProductBrand())){
+//                    // 跟着品牌走
+//                    fullReductionMap.put(brandName,fullReductionEntity);
+//                }else{
+//                    // 跟着条码走
+//                    fullReductionMap.put(fullReductionEntity.getBarcode(), fullReductionEntity);
+//                }
+//                skuActivitiesMap.put("mj",fullReductionMap);
+//            }
+//        }
+//
+//        *//**
+//         * 满赠可能是跟着条码,也可能跟着品牌
+//         * 根据商品品牌跟商品条码去查询是否有满赠
+//         * 1.先扫买的商品,然后查询出赠送的商品条码
+//         * 2.先扫赠的商品,然后查询出符合条件的商品条码或者品牌
+//         * 满足的金额   购买的商品条码或者品牌   赠送的商品条码
+//         * TODO
+//         *//*
+//        Map<String,Object> fullGiftMap = new HashMap<>();
+//        if(fullGift){
+//            String mkaId = mkaIdMap.get("mz");
+//            MkActivitiesFullGiftEntity giftEntity = fullGiftService.queryByCodeOrBrand(mkaId,prodBarcode,brandName,nowTime);
+//            if(giftEntity != null) {
+//                if(giftEntity.getProductBrand() != null){
+//                    // 跟着品牌走
+//                    fullGiftMap.put(brandName,giftEntity);
+//                }else{
+//                    // 跟着条码走
+//                    fullGiftMap.put(giftEntity.getBarcode(), giftEntity);
+//                }
+//                skuActivitiesMap.put("mz",fullGiftMap);
+//            }
+//        }
+//
+//        *//**
+//         * 买一送一可能是跟着条码,也可能跟着品牌
+//         * 根据商品品牌跟商品条码去查询是否有送的商品
+//         * 有两个场景
+//         * 1.先扫买的商品,然后查询出赠送的商品条码
+//         * 2.先扫赠的商品,然后查询出符合条件的商品条码或者品牌
+//         * 所以就需要一个map
+//         * key为购买的商品条码或者商品品牌  value为赠送的商品条码
+//         * 但是品牌是根据条码查询的,所以最终map里面的结构是
+//         * key 商品条码 value 赠品条码
+//         *//*
+//        if(getOneFree){
+//            String mkaId = mkaIdMap.get("mysy");
+//            MkActivitiesGetOneFreeGoodsEntity getOneFreeGoodsEntity = getOneFreeGoodsService.queryByCodeOrBrand(mkaId,prodBarcode,brandName);
+//            if(getOneFreeGoodsEntity != null){
+//                if("无".equals(getOneFreeGoodsEntity.getProductBrand())){
+//                    getOneFreeGoodsEntity.setBrand(false);
+//                    skuActivitiesMap.put("mysy",getOneFreeGoodsEntity);
+//                }else{
+//                    getOneFreeGoodsEntity.setBrand(true);
+//                    skuActivitiesMap.put("mysy",getOneFreeGoodsEntity);
+//                }
+//
+//            }
+//        }
+//
+//
+//        // 第二份半价
+//        if(halfPrice){
+//            String mkaId = mkaIdMap.get("drjbj");
+//            MkActivitiesHalfPriceEntity activitiesHalfPriceEntity = halfPriceService.queryByCodeOrBrand(mkaId,prodBarcode);
+//            if(activitiesHalfPriceEntity != null){
+//                skuActivitiesMap.put("drjbj",activitiesHalfPriceEntity);
+//
+//            }
+//
+//        }
+//
+//
+//        // --------------------------------------------------------------------------------------
+//
+//        *//**
+//         * 优惠券跟着条形码走,一般是设置一个标识,然后最后输入优惠券码后,减扣对应的标识,所以返回一个map数组
+//         *//*
+//
+//        if(coupon){
+//            String mkaId = mkaIdMap.get("yhq");
+//            MkActivitiesCouponEntity couponEntity =  couponService.queryByBarCode(mkaId,prodBarcode,nowTime);
+//            if(couponEntity != null){ // 优惠券码,优惠金额
+//                Map<String,Object> returnMap = new HashMap<>();
+//                returnMap.put(couponEntity.getCouponSn() , couponEntity.getCouponPrice());
+//                skuActivitiesMap.put("yhq",returnMap);
+//            }
+//        }
+//
+//
+//        *//**
+//         * 打折的价格是与条形码对应的,所以需要根据条形码和营销方式id去查询活动价格
+//         *//*
+//
+//        if(discount){
+//            String mkaId = mkaIdMap.get("dz");
+//            MkActivitiesDiscountEntity discountEntity =  discountService.queryByBarCode(mkaId,prodBarcode);
+//            // TODO 可能会直接替代产品价格
+//            if (discountEntity != null) {
+//                goods.setActualPaymentAmount(discountEntity.getActivityPrice());
+//                goods.setRetailPrice(discountEntity.getActivityPrice());
+//
+//                goods.setActivity("打折");
+//            }
+//        }
+//
+//
+//        *//**
+//         * 日常活动跟着条形码走,优先级比临时促销低,但是高于正常价格
+//         *//*
+//        if(daily){
+//            String mkaId = mkaIdMap.get("rchd");
+//            MkDailyActivitiesEntity dailyActivitiesEntity = dailyActivitiesService.queryByBarCode(mkaId,prodBarcode);
+//            if(dailyActivitiesEntity != null){
+//                goods.setActualPaymentAmount(dailyActivitiesEntity.getActivityPrice());
+//                goods.setRetailPrice(dailyActivitiesEntity.getActivityPrice());
+//
+//                goods.setActivity("日常活动");
+//
+//            }
+//        }
+//
+//
+//        *//**
+//         * 临时促销跟着条形码走,优先级应该最高,所以排到了最下面
+//         *//*
+//        if(promotion){
+//            String mkaId = mkaIdMap.get("lscx");
+//            MkActivitiesPromotionEntity promotionEntity = promotionService.queryByBarCode(mkaId,prodBarcode);
+//            // 如果该商品存在临时促销,直接替换活动价格
+//            if(promotionEntity != null){
+//                goods.setActualPaymentAmount(promotionEntity.getActivityPrice());
+//                goods.setRetailPrice(promotionEntity.getActivityPrice());
+//
+//                goods.setActivity("临时促销");
+//
+//            }
+//        }*/
 
         // 计算税费
         GoodsEntity goodsEntity = goodsDao.queryByBarcodeAndSku(prodBarcode, goods.getGoodsSn());
         BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity,goods.getActualPaymentAmount(),this).setScale(3,RoundingMode.HALF_UP);
         goods.setGoodstaxes(tax.toString());
-
+        goods.setSellVolume(1);
 
         skuActivitiesMap.put("goods",goods);
         return skuActivitiesMap;
@@ -2714,5 +2762,15 @@ public class GoodsServiceImpl implements GoodsService {
 
     }
 
-
+    /**
+     * 根据产品条码和sku查询保税展示补货的商品
+     *
+     * @param prodBarcode 商品条码
+     * @param sku         sku
+     * @return 商品信息
+     */
+    @Override
+    public GoodsEntity queryGoodsInfoByProductBarcodeAndSku(String prodBarcode, String sku) {
+        return goodsDao.queryGoodsInfoByProductBarcodeAndSku(prodBarcode, sku);
+    }
 }

+ 22 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/MkActivitiesFullGiftServiceImpl.java

@@ -150,4 +150,26 @@ public class MkActivitiesFullGiftServiceImpl implements MkActivitiesFullGiftServ
     public MkActivitiesFullGiftEntity queryByCodeOrBrand(String mkaId, String prodBarcode, String brandName, String nowTime) {
         return mkActivitiesFullGiftDao.queryByCodeOrBrand(mkaId,prodBarcode,brandName,nowTime);
     }
+
+    /**
+     * 根据营销活动编号获取满赠活动信息
+     *
+     * @param mkaIdList 营销活动编号集合
+     * @return 满赠营销活动信息
+     */
+    @Override
+    public List<MkActivitiesFullGiftEntity> queryByMkaIdList(List<Long> mkaIdList) {
+        return mkActivitiesFullGiftDao.queryByMkaIdList(mkaIdList);
+    }
+
+    /**
+     * 查询活动id对应的满赠活动规则
+     * @param mkaId 活动id
+     * @param storeId 门店id
+     * @return      满赠活动规则
+     */
+    @Override
+    public MkActivitiesFullGiftEntity queryObjectByMkaIdAndStoreId(Integer mkaId, String storeId) {
+        return mkActivitiesFullGiftDao.queryObjectByMkaIdAndStoreId(mkaId, storeId);
+    }
 }

+ 12 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/MkActivitiesPromotionServiceImpl.java

@@ -156,4 +156,16 @@ public class MkActivitiesPromotionServiceImpl implements MkActivitiesPromotionSe
     public void updatePriceBySku(String updatePrice, String sku, Long mkaId) {
         mkActivitiesPromotionDao.updatePriceBySku(updatePrice,sku,mkaId);
     }
+
+    /**
+     * 查询活动id对应的限时特价活动规则
+     *
+     * @param mkaId   活动id
+     * @param storeId 门店id
+     * @return 限时特价活动规则
+     */
+    @Override
+    public List<MkActivitiesPromotionEntity> queryListByMkaIdAndStoreId(int mkaId, String storeId) {
+        return mkActivitiesPromotionDao.queryListByMkaIdAndStoreId(mkaId, storeId);
+    }
 }

+ 404 - 25
kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java

@@ -22,6 +22,7 @@ import com.kmall.admin.dao.vip.Mall2PointsRulesDao;
 import com.kmall.admin.dto.*;
 import com.kmall.admin.entity.*;
 import com.kmall.admin.entity.kmall2eccs.KtoEccsEntity;
+import com.kmall.admin.entity.mk.MkActivitiesEntity;
 import com.kmall.admin.entity.mk.store.MkStorePromOrderRealEntity;
 import com.kmall.admin.entity.record.NewRetailOrderRestoreStockRecordEntity;
 import com.kmall.admin.entity.vip.Mall2MemberConsumptionRecordsEntity;
@@ -29,6 +30,8 @@ import com.kmall.admin.entity.vip.Mall2MemberPointsEntity;
 import com.kmall.admin.entity.vip.Mall2PointsRulesEntity;
 import com.kmall.admin.fromcomm.dao.SysConfigDao;
 import com.kmall.admin.fromcomm.entity.SysUserEntity;
+import com.kmall.admin.haikong.constant.Constants;
+import com.kmall.admin.haikong.dto.WareQueryStockResponseDTO;
 import com.kmall.admin.haikong.utils.ListUtils;
 import com.kmall.admin.haikong.vo.QueryGoodsVo;
 import com.kmall.admin.haikong.client.HaiKongMemberTemplate;
@@ -38,6 +41,7 @@ import com.kmall.admin.haikong.dto.MemberInfoDTO;
 import com.kmall.admin.haikong.utils.Response;
 import com.kmall.admin.service.*;
 import com.kmall.admin.service.kmall2eccs.KtoEccsService;
+import com.kmall.admin.service.mk.MkActivitiesService;
 import com.kmall.admin.service.mk.store.MkStoreCampMinusService;
 import com.kmall.admin.service.mk.store.MkStoreTicketDiscountService;
 import com.kmall.admin.service.record.NewRetailOrderRestoreStockRecordService;
@@ -48,6 +52,7 @@ import com.kmall.admin.utils.data.response.ResponseMessageData;
 import com.kmall.admin.utils.jackson.JacksonUtil;
 import com.kmall.admin.utils.oms.OmsSign;
 import com.kmall.admin.utils.pdf.BarcodeUtil;
+import com.kmall.admin.vo.CalculateOrderDiscountPriceVo;
 import com.kmall.admin.websocket.WebSocketServer;
 import com.kmall.api.entity.OrderGoodsRestoreVo;
 import com.kmall.api.entity.OrderGoodsVo;
@@ -77,6 +82,7 @@ import com.kmall.manager.manager.redis.JedisUtil;
 import com.kmall.manager.manager.wechat.WechatUtil;
 import com.kmall.manager.manager.wechat.wxglobal.dto.WechatGlobalRefundApiResult;
 import okhttp3.Request;
+import org.apache.shiro.crypto.hash.Hash;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
@@ -95,6 +101,7 @@ import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 
@@ -194,9 +201,6 @@ public class OrderServiceImpl implements OrderService {
     private Mall2LowPriceWarningDao lowPriceWarningDao;
 
     @Autowired
-    private MkActivitiesCouponService mkActivitiesCouponService;
-
-    @Autowired
     private OrderRefundService orderRefundService;
     @Autowired
     private OrderExceptionRecordService orderExceptionRecordService;
@@ -220,6 +224,26 @@ public class OrderServiceImpl implements OrderService {
     @Autowired
     private HaiKongProperties haiKongProperties;
 
+    @Autowired
+    private MkActivitiesService mkActivitiesService;
+
+    /**
+     * 满赠
+     */
+    @Autowired
+    private MkActivitiesFullGiftService mkActivitiesFullGiftService;
+
+    /**
+     * 优惠券
+     */
+    @Autowired
+    private MkActivitiesCouponService mkActivitiesCouponService;
+
+    /**
+     * 限时特价
+     */
+    @Autowired
+    private MkActivitiesPromotionService mkActivitiesPromotionService;
 
     @Override
     public OrderEntity queryObject(Long id) {
@@ -2036,9 +2060,23 @@ public class OrderServiceImpl implements OrderService {
             LOGGER.error("调用库存系统接口出现错误!返回结果为空!");
             throw new ServiceException("调用库存系统接口出现错误!");
         }
-        // TODO 解析xml,组装成map key=>sku value=>库存
+        WareQueryStockResponseDTO wareQueryStockResponseDTO = JacksonUtil.fromStringJson(queryWarehouseStockResponse, WareQueryStockResponseDTO.class);
+        if (Objects.isNull(wareQueryStockResponseDTO)) {
+            throw new ServiceException("解析一步达库存系统响应数据出现错误!");
+        }
+        List<WareQueryStockResponseDTO.WareQueryStockResponseItemDTO> items = wareQueryStockResponseDTO.getItems();
+        // 解析xml,组装成map key=>sku value=>库存
         Map<String, Integer> stockMap = new HashMap<>(16);
-
+        items.forEach(item -> {
+            String itemCode = item.getItemCode();
+            Integer quantity = item.getQuantity();
+            if (stockMap.containsKey(itemCode)) {
+                // 避免出现sku相同情况
+                stockMap.put(itemCode, stockMap.get(itemCode) + quantity);
+            } else {
+                stockMap.put(itemCode, quantity);
+            }
+        });
         // 订单总价格(含税价)
         BigDecimal orderPrice = BigDecimal.ZERO;
         // 商品总价格(不含税)
@@ -2047,6 +2085,7 @@ public class OrderServiceImpl implements OrderService {
         BigDecimal totalTax = BigDecimal.ZERO;
 
         List<OrderGoodsEntity> orderGoodsEntities = new ArrayList<>();
+        List<GoodsEntity> goodsEntities = new ArrayList<>();
 
         // TODO 根据商品条码、sku、门店id查询相对应的商品信息,并组装成对象
         List<QueryGoodsVo> queryGoodsVoList = new ArrayList<>();
@@ -2057,7 +2096,7 @@ public class OrderServiceImpl implements OrderService {
             queryGoodsVo.setStoreId(storeId);
             queryGoodsVo.setSellVolume((Integer) map.get("sellVolume"));
             queryGoodsVo.setRetailPrice(new BigDecimal(String.valueOf(map.get("retailPrice"))));
-            queryGoodsVo.setGoodstaxes(new BigDecimal(String.valueOf(map.get("goodstaxes"))));
+            queryGoodsVo.setGoodsTaxes(new BigDecimal(String.valueOf(map.get("goodstaxes"))));
             queryGoodsVo.setDisCountedPrice(new BigDecimal(String.valueOf(map.get("disCountedPrice"))));
             queryGoodsVoList.add(queryGoodsVo);
         });
@@ -2066,6 +2105,9 @@ public class OrderServiceImpl implements OrderService {
         // 复制集合数据
         ListUtils listUtils = BeanUtils.instantiate(ListUtils.class);
         listUtils.copyList(goodsEntityList, queryGoodsVoList);
+        // 用来存储是否达到满赠条件的map
+        Map<String, BigDecimal> categoryConditionMap = new HashMap<>();
+        Map<String, BigDecimal> brandConditionMap = new HashMap<>();
 
         for (QueryGoodsVo goodsEntity : queryGoodsVoList) {
             OrderGoodsEntity orderGoodsEntity = new OrderGoodsEntity();
@@ -2078,7 +2120,7 @@ public class OrderServiceImpl implements OrderService {
             // 订单金额(含税价),订单总金额,用户支付的金额
             BigDecimal retailPrice = goodsEntity.getRetailPrice();
             // 商品预估税率
-            BigDecimal goodsTaxes = goodsEntity.getGoodstaxes();
+            BigDecimal goodsTaxes = goodsEntity.getGoodsTaxes();
             // 商品优惠金额
             BigDecimal disCountedPrice = goodsEntity.getDisCountedPrice();
             // 商品金额(不包含税的价格),推送海关电子订单需要
@@ -2089,29 +2131,91 @@ public class OrderServiceImpl implements OrderService {
             totalTax = totalTax.add(goodsTaxes);
             // 当前sku
             String currentSku = goodsEntity.getSku();
-            // TODO 判断库存。。
-            if (!stockMap.containsKey(currentSku)) {
-                LOGGER.error("库存系统中不包含此sku:【{}】,校验库存出错!下单失败!", currentSku);
-                throw new ServiceException(String.format("不包含此sku:【%s】", currentSku));
-            }
             // 仓库库存
             Integer warehouseStock = stockMap.get(currentSku);
-            // 当前出区数
-            Integer exitRegionNumber = goodsEntity.getExitRegionNumber();
             // 门店库存
             Integer stockNum = goodsEntity.getStockNum();
-            // 保税仓库存 + 门店库存 - 出区数 >= 购买数
-            if (!((warehouseStock + stockNum) - exitRegionNumber >= sellVolume)) {
-                // 库存不足
-                LOGGER.error("sku【{}】库存不足!商品条码:【{}】,门店库存:【{}】,保税仓库存:【{}】,当前出区数:【{}】", currentSku, prodBarcode, stockNum, warehouseStock, exitRegionNumber);
-                throw new ServiceException(String.format("sku【%s】库存不足!商品条码:【%s】,门店库存:【%s】,保税仓库存:【%s】,当前出区数:【%s】", currentSku, prodBarcode, stockNum, warehouseStock, exitRegionNumber));
+            // 判断库存。。
+            if (!stockMap.containsKey(currentSku)) {
+                LOGGER.error("库存系统中不包含此sku:【{}】,校验库存出错!下单失败!", currentSku);
+                throw new ServiceException(String.format("不包含此sku:【%s】", currentSku));
+            } else {
+                // 保税仓库存 + 展销店库存 - 出区数 >= 购买数
+                // 当前出区数
+                Integer exitRegionNumber = goodsEntity.getExitRegionNumber();
+                // 保税仓库存 + 门店库存 - 出区数 >= 购买数
+                if (!((warehouseStock + stockNum) - exitRegionNumber >= sellVolume)) {
+                    // 库存不足
+                    LOGGER.error("sku【{}】库存不足!商品条码:【{}】,门店库存:【{}】,保税仓库存:【{}】,当前出区数:【{}】", currentSku, prodBarcode, stockNum, warehouseStock, exitRegionNumber);
+                    throw new ServiceException(String.format("sku【%s】库存不足!商品条码:【%s】,门店库存:【%s】,保税仓库存:【%s】,当前出区数:【%s】", currentSku, prodBarcode, stockNum, warehouseStock, exitRegionNumber));
+                }
             }
             // 设置订单详情信息
             GoodsEntity entity = new GoodsEntity(goodsEntity);
-            orderGoodsEntity = wrapOrderGoods(orderGoodsEntity, entity);
+            wrapOrderGoods(orderGoodsEntity, entity);
             orderGoodsEntities.add(orderGoodsEntity);
+
+            // 设置条件信息,暂不支持门店满赠活动
+            String categoryId = String.valueOf(entity.getCategoryId());
+            String brandId = String.valueOf(entity.getBrandId());
+            if (!categoryConditionMap.containsKey(categoryId)) {
+                categoryConditionMap.put(categoryId, retailPrice);
+            } else {
+                categoryConditionMap.put(categoryId, categoryConditionMap.get(categoryId).add(retailPrice));
+            }
+//            if (!brandConditionMap.containsKey(brandId)) {
+//                brandConditionMap.put(brandId, retailPrice);
+//            } else {
+//                brandConditionMap.put(brandId, brandConditionMap.get(brandId).add(retailPrice));
+//            }
         }
-        // 2. 校验是否是会员,调用会员系统查询会员信息,查询接口:
+        // 2. 判断购买的商品是否能参与满减活动
+        // 2.1 查询当前门店是否有满赠的活动
+        List<MkActivitiesEntity> activitiesEntities = mkActivitiesService.queryByNowByMz(String.valueOf(storeId), DateUtils.format(new Date(), "yyyy-MM-dd"));
+        if (CollectionUtils.isEmpty(activitiesEntities)) {
+            LOGGER.error("----- 该门店【{}】暂无满赠活动! -----", storeId);
+        } else {
+            // 当前门店的活动编号
+            List<Long> activitiesSnList = activitiesEntities.stream().map(MkActivitiesEntity::getMkaId).collect(Collectors.toList());
+            // 活动
+            List<MkActivitiesFullGiftEntity> mkActivitiesFullGiftEntities = mkActivitiesFullGiftService.queryByMkaIdList(activitiesSnList);
+            if (CollectionUtils.isEmpty(mkActivitiesFullGiftEntities)) {
+                LOGGER.error("----- 该门店【{}】暂无满赠活动! -----", storeId);
+            } else {
+                mkActivitiesFullGiftEntities.forEach(mkActivitiesFullGiftEntity -> {
+                    // 存在品牌满赠活动,暂不支持品牌满赠活动
+//                    String brandId = String.valueOf(mkActivitiesFullGiftEntity.getBrandId());
+//                    if (brandConditionMap.containsKey(brandId)) {
+//                        if (brandConditionMap.get(brandId).compareTo(mkActivitiesFullGiftEntity.getQualifiedAmount()) > 0) {
+//                            // 该品牌满足满赠条件
+//
+//                        }
+//                    }
+                    // 存在分类满赠活动
+                    String categoryId = String.valueOf(mkActivitiesFullGiftEntity.getCategoryId());
+                    if (!CollectionUtils.isEmpty(categoryConditionMap) && categoryConditionMap.containsKey(categoryId)) {
+                        if (categoryConditionMap.get(categoryId).compareTo(mkActivitiesFullGiftEntity.getQualifiedAmount()) > 0) {
+                            // 该分类满足满赠条件
+                            String giftBarcode = mkActivitiesFullGiftEntity.getGiftBarcode();
+                            String giftGoodsSn = mkActivitiesFullGiftEntity.getGiftGoodsSn();
+                            String shopSn = mkActivitiesFullGiftEntity.getShopSn();
+                            GoodsEntity goodsEntity = goodsService.queryGoodsStockByBarcodeAndStoreIdAndSku(giftBarcode, Integer.parseInt(shopSn), giftGoodsSn);
+                            // 存储赠送数
+                            goodsEntity.setGoodsNumber(mkActivitiesFullGiftEntity.getGiftNumber());
+                            OrderGoodsEntity orderGoodsEntity = new OrderGoodsEntity();
+                            wrapOrderGoods(orderGoodsEntity, goodsEntity);
+                            orderGoodsEntity.setRetailPrice(BigDecimal.ZERO);
+                            orderGoodsEntity.setDiscountedPrice(BigDecimal.ZERO);
+                            orderGoodsEntity.setActualPaymentAmount(BigDecimal.ZERO);
+                            orderGoodsEntities.add(orderGoodsEntity);
+                        }
+                    }
+                });
+            }
+        }
+
+
+        // 3. 校验是否是会员,调用会员系统查询会员信息,查询接口:
         // 优惠后价格
         BigDecimal afterDiscountPrice;
         if (org.springframework.util.StringUtils.isEmpty(couponBarCode)) {
@@ -2136,6 +2240,7 @@ public class OrderServiceImpl implements OrderService {
                         afterDiscountPrice = calculatePreferentialPrice(orderPrice, 0, goodsList, storeId, userInfo);
                     }
                 } else {
+                    LOGGER.error("查询会员信息失败!响应结果:{}", queryMemberInfoResponse);
                     throw new ServiceException("查询会员信息失败!请重新下单!");
                 }
             } catch (Exception e) {
@@ -2143,7 +2248,7 @@ public class OrderServiceImpl implements OrderService {
                 throw new ServiceException("查询会员信息失败!请重新下单!");
             }
         }
-        // 3. 调用付款接口
+        // 4. 调用付款接口
         // 判断是微信的支付码还是支付宝的支付码
         if (parCode.startsWith("28")) {
             // 支付宝支付
@@ -2163,9 +2268,9 @@ public class OrderServiceImpl implements OrderService {
             }
         }
 
-        // 4. 扣减库存
+        // 5. 扣减库存
 
-        // 5. 推送订单到免税mall
+        // 6. 订单入库
 
 
         return resultObj;
@@ -2181,7 +2286,9 @@ public class OrderServiceImpl implements OrderService {
         // 设置商品信息
         BeanUtils.copyProperties(goodsEntity, orderGoodsEntity);
         // 设置订单信息
-        
+        // 销售数
+        orderGoodsEntity.setNumber(goodsEntity.getGoodsNumber());
+        // TODO other...
         return orderGoodsEntity;
     }
 
@@ -3873,6 +3980,278 @@ public class OrderServiceImpl implements OrderService {
             return TicketPrintUtil.print(head, goodsList, cashInfo, cusListing, mailInfo);
     }
 
+    /**
+     * 计算优惠价格,活动价格
+     *
+     * @param calculateOrderDiscountPriceVo 请求参数
+     * @return 商品集合
+     */
+    @Override
+    public List<GoodsDetailsDto> calculateOrderDiscountPrice(CalculateOrderDiscountPriceVo calculateOrderDiscountPriceVo) {
+        if (Objects.isNull(calculateOrderDiscountPriceVo)) {
+            LOGGER.error("计算活动优惠价格,请求参数为null!");
+            throw new ServiceException("计算活动优惠价格,请求参数为null!");
+        }
+        String storeId = calculateOrderDiscountPriceVo.getStoreId();
+        List<GoodsDetailsDto> goodsDetailsDtos = calculateOrderDiscountPriceVo.getGoodsList();
+        List<QueryGoodsVo> goodsVos = goodsDetailsDtos.stream().map(good -> {
+            QueryGoodsVo queryGoodsVo = new QueryGoodsVo();
+            BeanUtils.copyProperties(good, queryGoodsVo);
+            queryGoodsVo.setSku(good.getGoodsSn());
+            queryGoodsVo.setStoreId(Integer.parseInt(storeId));
+            return queryGoodsVo;
+        }).collect(Collectors.toList());
+
+        // 查询商品表
+        List<GoodsEntity> goodsEntities = goodsService.queryGoodsStockByQueryGoodsVoList(goodsVos);
+
+        /*
+         * 2.查询当前时间,该门店是否有活动,如果有活动,查询开启了哪些营销方式
+         * 参数: 当前时间  门店id
+         */
+        List<MkActivitiesEntity> mkActivitiesEntityList = mkActivitiesService.queryByNow(storeId, DateUtils.format(new Date(), "yyyy-MM-dd"));
+
+        /*
+         * 活动相关规则:
+         * 1. 优先优惠券再去计算积分
+         * 2. 满赠的赠品商品在推送定时时零售价为0
+         * 3. 任何活动都优先于积分计算
+         * 4. 活动之间具有互斥性
+         */
+        if (CollectionUtils.isEmpty(mkActivitiesEntityList)) {
+            LOGGER.info("当前时间门店【{}】,无相关活动信息!", storeId);
+            for (GoodsDetailsDto goodsDetailsDto : goodsDetailsDtos) {
+                GoodsEntity goodsEntity = new GoodsEntity();
+                BeanUtils.copyProperties(goodsDetailsDto, goodsEntity);
+                goodsEntity.setGoodsRate(new BigDecimal(goodsDetailsDto.getGoodsRate()));
+                // 无活动情况,实际支付价 = 零售价
+                BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity , goodsEntity.getRetailPrice(), goodsService).setScale(3,RoundingMode.HALF_UP);
+                // 预估税
+                goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                // TODO 测试用
+                goodsDetailsDto.setActualPaymentAmount(BigDecimal.ZERO);
+            }
+            return goodsDetailsDtos;
+        }
+
+        List<Integer> brandIdList = goodsEntities.stream().map(GoodsEntity::getBrandId).collect(Collectors.toList());
+        List<Integer> categoryIdList = goodsEntities.stream().map(GoodsEntity::getCategoryId).collect(Collectors.toList());
+
+        AtomicBoolean activityFlag = new AtomicBoolean(false);
+        // 判断活动类型,并确定购物栏中商品是否满足活动条件
+        mkActivitiesEntityList.forEach(mkActivitiesEntity -> {
+            String mkaStoreId = mkActivitiesEntity.getMkaStoreId();
+            Long mkaId = mkActivitiesEntity.getMkaId();
+            String mkaTopic = mkActivitiesEntity.getMkaTopic();
+            Constants.ActivityTopicEnum activityTopicEnum = Constants.ActivityTopicEnum.valueOf(mkaTopic);
+            switch (activityTopicEnum) {
+                case MZ:
+                    // 判断商品是否符合满赠活动要求
+                    MkActivitiesFullGiftEntity mkActivitiesFullGiftEntity = mkActivitiesFullGiftService.queryObjectByMkaIdAndStoreId(mkaId.intValue(), storeId);
+                    if (Objects.isNull(mkActivitiesFullGiftEntity)) {
+                        LOGGER.error("查询满赠活动信息结果为空!mka_id:{}, store_id:{}", mkaId, storeId);
+                        throw new ServiceException(String.format("查询满赠活动信息结果为空!mka_id:%s, store_id:%s", mkaId, storeId));
+                    }
+                    Long brandId = mkActivitiesFullGiftEntity.getBrandId();
+                    Long categoryId = mkActivitiesFullGiftEntity.getCategoryId();
+                    Constants.ActivityType fullGiftActivityType = Constants.ActivityType.valueOf(mkActivitiesFullGiftEntity.getFullGiftType());
+                    switch (fullGiftActivityType) {
+                        case BRAND:
+                            if (brandIdList.contains(brandId.intValue())) {
+                                // 活动包含该商品品牌,此次订单该品牌商品
+                                List<GoodsEntity> goodsEntityList = goodsEntities.stream().filter(goodsEntity -> brandId.intValue() == goodsEntity.getBrandId()).collect(Collectors.toList());
+                                AtomicReference<BigDecimal> brandTotalPrice = new AtomicReference<>(BigDecimal.ZERO);
+                                goodsEntityList.forEach(goodsEntity -> {
+                                    brandTotalPrice.set(brandTotalPrice.get().add(goodsEntity.getRetailPrice()));
+                                });
+                                if (brandTotalPrice.get().compareTo(mkActivitiesFullGiftEntity.getQualifiedAmount()) >= 0) {
+                                    // 满足满赠条件
+                                    String giftGoodsSn = mkActivitiesFullGiftEntity.getGiftGoodsSn();
+                                    String giftBarcode = mkActivitiesFullGiftEntity.getGiftBarcode();
+                                    GoodsEntity goodsEntity = goodsService.queryGoodsStockByBarcodeAndStoreIdAndSku(giftBarcode, Integer.parseInt(mkaStoreId), giftGoodsSn);
+                                    GoodsDetailsDto goodsDetailsDto = new GoodsDetailsDto();
+                                    BeanUtils.copyProperties(goodsEntity, goodsDetailsDto);
+                                    // 除了限时促销(需要向海关备案),其它活动都拿海关备案价来算税款
+                                    BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, goodsEntity.getRetailPrice(), goodsService).setScale(3, RoundingMode.HALF_UP);
+                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                    goodsDetailsDto.setActualPaymentAmount(BigDecimal.ZERO);
+                                    goodsDetailsDto.setActivity("满赠商品");
+                                    goodsDetailsDto.setGiftNumber(mkActivitiesFullGiftEntity.getGiftNumber());
+                                    goodsDetailsDto.setDiscountedPrice(goodsEntity.getRetailPrice());
+                                    // 添加进商品详情列表
+                                    goodsDetailsDtos.add(goodsDetailsDto);
+                                }
+                            }
+                            break;
+                        case CATEGORY:
+                            if (categoryIdList.contains(categoryId.intValue())) {
+                                // 活动包含该商品分类
+                                List<GoodsEntity> goodsEntityList = goodsEntities.stream().filter(goodsEntity -> brandId.equals(mkActivitiesFullGiftEntity.getCategoryId())).collect(Collectors.toList());
+                                AtomicReference<BigDecimal> categoryTotalPrice = new AtomicReference<>(BigDecimal.ZERO);
+                                goodsEntityList.forEach(goodsEntity -> {
+                                    categoryTotalPrice.set(categoryTotalPrice.get().add(goodsEntity.getRetailPrice()));
+                                });
+                                if (categoryTotalPrice.get().compareTo(mkActivitiesFullGiftEntity.getQualifiedAmount()) >= 0) {
+                                    // 满足满赠条件
+                                    String giftGoodsSn = mkActivitiesFullGiftEntity.getGiftGoodsSn();
+                                    String giftBarcode = mkActivitiesFullGiftEntity.getGiftBarcode();
+                                    GoodsEntity goodsEntity = goodsService.queryGoodsStockByBarcodeAndStoreIdAndSku(giftBarcode, Integer.parseInt(mkaStoreId), giftGoodsSn);
+                                    GoodsDetailsDto goodsDetailsDto = new GoodsDetailsDto();
+                                    BeanUtils.copyProperties(goodsEntity, goodsDetailsDto);
+                                    // 除了限时促销(需要向海关备案),其它活动都拿海关备案价来算税款
+                                    BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, goodsEntity.getRetailPrice(), goodsService).setScale(3, RoundingMode.HALF_UP);
+                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                    goodsDetailsDto.setActualPaymentAmount(BigDecimal.ZERO);
+                                    goodsDetailsDto.setActivity("满赠商品");
+                                    goodsDetailsDto.setGiftNumber(mkActivitiesFullGiftEntity.getGiftNumber());
+                                    goodsDetailsDto.setDiscountedPrice(goodsEntity.getRetailPrice());
+                                    // 添加进商品详情列表
+                                    goodsDetailsDtos.add(goodsDetailsDto);
+                                }
+                            }
+                            break;
+                        default:
+                            LOGGER.error("未知满赠类型【{},{}】!请联系管理员!", fullGiftActivityType.getActivityType(), fullGiftActivityType.getActivityTypeCode());
+                            throw new ServiceException(String.format("未知满赠类型【%s,%s】!请联系管理员!", fullGiftActivityType.getActivityType(), fullGiftActivityType.getActivityTypeCode()));
+                    }
+                    break;
+                case YHJ:
+                    // 判断商品是否符合优惠券活动要求
+                    Map<String, Object> params = new HashMap<>();
+                    params.put("shop_sn", storeId);
+                    params.put("mka_id", mkaId);
+                    List<MkActivitiesCouponEntity> mkActivitiesCouponEntities = mkActivitiesCouponService.queryList(params);
+                    if (CollectionUtils.isEmpty(mkActivitiesCouponEntities)) {
+                        LOGGER.error("查询优惠券活动信息结果为空!mka_id:{}, store_id:{}", mkaId, storeId);
+                        throw new ServiceException(String.format("查询优惠券活动信息结果为空!mka_id:%s, store_id:%s", mkaId, storeId));
+                    }
+                    MkActivitiesCouponEntity mkActivitiesCouponEntity = mkActivitiesCouponEntities.get(0);
+                    Integer couponEntityBrandId = mkActivitiesCouponEntity.getBrandId();
+                    Integer couponEntityCategoryId = mkActivitiesCouponEntity.getCategoryId();
+                    Integer couponEntityStoreId = Integer.parseInt(mkActivitiesCouponEntity.getShopSn());
+                    BigDecimal couponPrice = mkActivitiesCouponEntity.getCouponPrice();
+                    Constants.ActivityType couponActivityType = Constants.ActivityType.valueOf(mkActivitiesCouponEntity.getActivityType());
+                    switch (couponActivityType) {
+                        case BRAND:
+                            goodsEntities.forEach(goodsEntity -> {
+                                if (couponEntityBrandId.equals(goodsEntity.getBrandId())) {
+                                    BigDecimal retailPrice = goodsEntity.getRetailPrice();
+                                    String sku = goodsEntity.getSku();
+                                    String prodBarcode = goodsEntity.getProdBarcode();
+                                    if (couponPrice.compareTo(retailPrice) <= 0) {
+                                        LOGGER.error("优惠券优惠金额【{}】大于或等于商品【条码:{},sku:{}】的零售价【{}】,请检查优惠券金额设置!", couponPrice, prodBarcode, sku, retailPrice);
+                                        throw new ServiceException(String.format("优惠券优惠金额【%s】大于或等于商品【条码:%s,sku:%s】的零售价【%s】,请检查优惠券金额设置!", couponPrice, prodBarcode, sku, retailPrice));
+                                    }
+                                    BigDecimal discountAfterPrice = retailPrice.subtract(couponPrice);
+                                    GoodsDetailsDto goodsDetailsDto = new GoodsDetailsDto();
+                                    BeanUtils.copyProperties(goodsEntity, goodsDetailsDto);
+                                    // 除了限时促销(需要向海关备案),其它活动都拿海关备案价来算税款
+                                    BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, goodsEntity.getRetailPrice(), goodsService).setScale(3, RoundingMode.HALF_UP);
+                                    goodsDetailsDto.setActualPaymentAmount(discountAfterPrice);
+                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                    goodsDetailsDto.setActivity("优惠券活动");
+                                    goodsDetailsDto.setDiscountedPrice(retailPrice.subtract(discountAfterPrice));
+                                    goodsDetailsDtos.add(goodsDetailsDto);
+                                }
+                            });
+                            break;
+                        case CATEGORY:
+                            goodsEntities.forEach(goodsEntity -> {
+                                if (couponEntityCategoryId.equals(goodsEntity.getCategoryId())) {
+                                    BigDecimal retailPrice = goodsEntity.getRetailPrice();
+                                    String sku = goodsEntity.getSku();
+                                    String prodBarcode = goodsEntity.getProdBarcode();
+                                    if (couponPrice.compareTo(retailPrice) <= 0) {
+                                        LOGGER.error("优惠券优惠金额【{}】大于或等于商品【条码:{},sku:{}】的零售价【{}】,请检查优惠券金额设置!", couponPrice, prodBarcode, sku, retailPrice);
+                                        throw new ServiceException(String.format("优惠券优惠金额【%s】大于或等于商品【条码:%s,sku:%s】的零售价【%s】,请检查优惠券金额设置!", couponPrice, prodBarcode, sku, retailPrice));
+                                    }
+                                    BigDecimal discountAfterPrice = retailPrice.subtract(couponPrice);
+                                    GoodsDetailsDto goodsDetailsDto = new GoodsDetailsDto();
+                                    BeanUtils.copyProperties(goodsEntity, goodsDetailsDto);
+                                    // 除了限时促销(需要向海关备案),其它活动都拿海关备案价来算税款
+                                    BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, goodsEntity.getRetailPrice(), goodsService).setScale(3, RoundingMode.HALF_UP);
+                                    goodsDetailsDto.setActualPaymentAmount(discountAfterPrice);
+                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                    goodsDetailsDto.setActivity("优惠券活动");
+                                    goodsDetailsDto.setDiscountedPrice(retailPrice.subtract(discountAfterPrice));
+                                    goodsDetailsDtos.add(goodsDetailsDto);
+                                }
+                            });
+                            break;
+                        case PRODUCT:
+                            mkActivitiesCouponEntities.forEach(mkActivitiesCouponEntity1 -> {
+                                // 单个商品优惠券,有多条记录
+                                String activityProductBarcode = mkActivitiesCouponEntity1.getBarcode();
+                                String activitySku = mkActivitiesCouponEntity1.getGoodsSn();
+                                goodsEntities.forEach(goodsEntity -> {
+                                    String sku = goodsEntity.getSku();
+                                    String prodBarcode = goodsEntity.getProdBarcode();
+                                    // 条码、sku、门店都需一致
+                                    if (activitySku.equals(sku) && activityProductBarcode.equals(prodBarcode) && couponEntityStoreId.equals(goodsEntity.getStoreId())) {
+                                        BigDecimal retailPrice = goodsEntity.getRetailPrice();
+                                        if (couponPrice.compareTo(retailPrice) <= 0) {
+                                            LOGGER.error("优惠券优惠金额【{}】大于或等于商品【条码:{},sku:{}】的零售价【{}】,请检查优惠券金额设置!", couponPrice, prodBarcode, sku, retailPrice);
+                                            throw new ServiceException(String.format("优惠券优惠金额【%s】大于或等于商品【条码:%s,sku:%s】的零售价【%s】,请检查优惠券金额设置!", couponPrice, prodBarcode, sku, retailPrice));
+                                        }
+                                        BigDecimal discountAfterPrice = retailPrice.subtract(couponPrice);
+                                        GoodsDetailsDto goodsDetailsDto = new GoodsDetailsDto();
+                                        BeanUtils.copyProperties(goodsEntity, goodsDetailsDto);
+                                        // 除了限时促销(需要向海关备案),其它活动都拿海关备案价来算税款
+                                        BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, goodsEntity.getRetailPrice(), goodsService).setScale(3, RoundingMode.HALF_UP);
+                                        goodsDetailsDto.setActualPaymentAmount(discountAfterPrice);
+                                        goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                        goodsDetailsDto.setActivity("优惠券活动");
+                                        goodsDetailsDto.setDiscountedPrice(retailPrice.subtract(discountAfterPrice));
+                                        goodsDetailsDtos.add(goodsDetailsDto);
+                                    }
+                                });
+                            });
+                            break;
+                        default:
+                            LOGGER.error("未知的优惠券活动分类类型:【{},{}】,请联系管理员!", activityTopicEnum.getTopicCode(), activityTopicEnum.getTopicName());
+                            throw new ServiceException(String.format("未知的优惠券活动分类类型:【%s,%s】,请联系管理员!", activityTopicEnum.getTopicCode(), activityTopicEnum.getTopicName()));
+                    }
+
+                    break;
+                case LSCX:
+                    // 判断商品是否符合限时特价活动要求
+                    List<MkActivitiesPromotionEntity> mkActivitiesPromotionEntities = mkActivitiesPromotionService.queryListByMkaIdAndStoreId(mkaId.intValue(), storeId);
+                    if (CollectionUtils.isEmpty(mkActivitiesPromotionEntities)) {
+                        LOGGER.error("查询临时促销活动信息结果为空!mka_id:{}, store_id:{}", mkaId, storeId);
+                        throw new ServiceException(String.format("查询临时促销活动信息结果为空!mka_id:%s, store_id:%s", mkaId, storeId));
+                    }
+                    // 限时特价,直接替换实际支付价即可,并且拿特价计算税款
+                    mkActivitiesPromotionEntities.forEach(mkActivitiesPromotionEntity -> {
+                        String entityBarcode = mkActivitiesPromotionEntity.getBarcode();
+                        String entityGoodsSn = mkActivitiesPromotionEntity.getGoodsSn();
+                        BigDecimal activityPrice = mkActivitiesPromotionEntity.getActivityPrice();
+                        String shopSn = mkActivitiesPromotionEntity.getShopSn();
+                        goodsEntities.forEach(goodsEntity -> {
+                            String sku = goodsEntity.getSku();
+                            String prodBarcode = goodsEntity.getProdBarcode();
+                            String storeId2 = String.valueOf(goodsEntity.getStoreId());
+                            BigDecimal retailPrice = goodsEntity.getRetailPrice();
+                            if (entityBarcode.equals(prodBarcode) && entityGoodsSn.equals(sku) && shopSn.equals(storeId2)) {
+                                GoodsDetailsDto goodsDetailsDto = new GoodsDetailsDto();
+                                BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, activityPrice, goodsService).setScale(3, RoundingMode.HALF_UP);
+                                BeanUtils.copyProperties(goodsDetailsDto, goodsEntity);
+                                goodsDetailsDto.setActualPaymentAmount(activityPrice);
+                                goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                goodsDetailsDto.setActivity("限时促销");
+                                goodsDetailsDto.setDiscountedPrice(retailPrice.subtract(activityPrice));
+                                goodsDetailsDtos.add(goodsDetailsDto);
+                            }
+                        });
+                    });
+                    break;
+                default:
+                    LOGGER.error("未知的满赠活动分类类型:【{},{}】,请联系管理员!", activityTopicEnum.getTopicCode(), activityTopicEnum.getTopicName());
+                    throw new ServiceException(String.format("未知的满赠活动分类类型:【%s,%s】,请联系管理员!", activityTopicEnum.getTopicCode(), activityTopicEnum.getTopicName()));
+            }
+        });
+        return goodsDetailsDtos;
+    }
+
 
     /**
      * 设置订单数据

+ 13 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/mk/MkActivitiesServiceImpl.java

@@ -115,6 +115,19 @@ public class MkActivitiesServiceImpl implements MkActivitiesService {
         return mkActivitiesDao.queryByNow(storeId,currentTime);
     }
 
+    /**
+     * 根据门店id和当前时间查询有哪些营销方式
+     * 查询当前时间是否有满赠的活动
+     *
+     * @param storeId     门店id
+     * @param currentTime 当前时间
+     * @return 满赠活动列表
+     */
+    @Override
+    public List<MkActivitiesEntity> queryByNowByMz(String storeId, String currentTime) {
+        return mkActivitiesDao.queryByNowByMz(storeId, currentTime);
+    }
+
     @Override
     public List<MkActivitiesEntity> queryByTopic(String storeId, String currentTime, String topic) {
         return mkActivitiesDao.queryByTopic(storeId,currentTime,topic);

+ 9 - 0
kmall-admin/src/main/java/com/kmall/admin/service/mk/MkActivitiesService.java

@@ -79,5 +79,14 @@ public interface MkActivitiesService {
      */
     List<MkActivitiesEntity> queryByNow(String storeId, String currentTime);
 
+    /**
+     * 根据门店id和当前时间查询有哪些营销方式
+     * 查询当前时间是否有满赠的活动
+     * @param storeId       门店id
+     * @param currentTime   当前时间
+     * @return              满赠活动列表
+     */
+    List<MkActivitiesEntity> queryByNowByMz(String storeId, String currentTime);
+
     List<MkActivitiesEntity> queryByTopic(String storeId, String format, String topic);
 }

+ 40 - 0
kmall-admin/src/main/java/com/kmall/admin/vo/CalculateOrderDiscountPriceVo.java

@@ -0,0 +1,40 @@
+package com.kmall.admin.vo;
+
+import com.kmall.admin.dto.GoodsDetailsDto;
+
+import java.util.List;
+
+/**
+ * @author lhm
+ * @createDate 2021-11-19
+ */
+public class CalculateOrderDiscountPriceVo {
+
+    private String storeId;
+
+    private List<GoodsDetailsDto> goodsList;
+
+    public CalculateOrderDiscountPriceVo() {
+    }
+
+    public CalculateOrderDiscountPriceVo(String storeId, List<GoodsDetailsDto> goodsList) {
+        this.storeId = storeId;
+        this.goodsList = goodsList;
+    }
+
+    public String getStoreId() {
+        return storeId;
+    }
+
+    public void setStoreId(String storeId) {
+        this.storeId = storeId;
+    }
+
+    public List<GoodsDetailsDto> getGoodsList() {
+        return goodsList;
+    }
+
+    public void setGoodsList(List<GoodsDetailsDto> goodsList) {
+        this.goodsList = goodsList;
+    }
+}

+ 10 - 3
kmall-admin/src/main/resources/mybatis/mapper/GoodsDao.xml

@@ -254,7 +254,7 @@
     <select id="queryGoodsDetailsByProdBarcode" resultType="com.kmall.admin.dto.GoodsDetailsDto">
         SELECT distinct
         a.goods_sn as GoodsSn,m.retail_price as retailPrice,a.prod_barcode as prodBarcode,a.name,a.brand,a.goods_desc as goodsDesc,a.goods_unit as goodsUnit,a.goods_rate as goodsRate,a.primary_pic_url ,m.stock_num as stockNum,r.value as specification
-        ,a.hs_code as hsCode , a.legal_unit1_qty as legalUnit1Qty , a.legal_unit2_qty as legalUnit2Qty,a.ciq_prod_model as ciqProdModel,a.to_be_restored
+        ,a.hs_code as hsCode , a.legal_unit1_qty as legalUnit1Qty , a.legal_unit2_qty as legalUnit2Qty,a.ciq_prod_model as ciqProdModel,a.to_be_restored, m.exit_region_number as exitRegionNumber
         FROM
             mall_goods a
         LEFT JOIN mall_goods_specification r ON r.goods_id = a.id
@@ -1142,8 +1142,9 @@
 
     <select id="queryGoodsStockByQueryGoodsVoList" resultType="com.kmall.admin.entity.GoodsEntity">
         SELECT
-            a.id,a.sku,a.goods_number,a.goods_sn,a.name,a.list_pic_url,a.prod_barcode,r.market_price storeMarketPrice,r.retail_price storeRetailPrice ,r.stock_num,s.store_name,r.product_id,s.id 'storeId',a.goods_rate as goodsRate,
-            a.hs_code as hsCode , a.legal_unit1_qty as legalUnit1Qty , a.legal_unit2_qty as legalUnit2Qty,a.ciq_prod_model as ciqProdModel,a.to_be_restored, r.stock_num, r.exit_region_number as exitRegionNumber
+            a.id,a.sku,a.goods_number,a.goods_sn,a.name,a.list_pic_url,a.prod_barcode,r.market_price storeMarketPrice, r.retail_price as retailPrice,r.retail_price storeRetailPrice ,r.stock_num,s.store_name,r.product_id,s.id 'storeId',a.goods_rate as goodsRate,
+            a.hs_code as hsCode , a.legal_unit1_qty as legalUnit1Qty , a.legal_unit2_qty as legalUnit2Qty,a.ciq_prod_model as ciqProdModel,a.to_be_restored, r.stock_num, r.exit_region_number as exitRegionNumber,
+            a.category_id as categoryId, a.brand_id as brandId
         FROM
             mall_goods a
         LEFT JOIN mall_product_store_rela r ON r.goods_id = a.id
@@ -1157,5 +1158,11 @@
         and r.stock_num > 0
     </select>
 
+    <!-- 根据产品条码和sku查询保税展示补货的商品 -->
+    <select id="queryGoodsInfoByProductBarcodeAndSku" resultMap="goodsMap">
+        select mg.*,
+        from mall_goods mg
+        where mg.goods_biz_type = '02' and mg.prod_barcode = #{prodBarcode} and mg.sku = #{sku}
+    </select>
 
 </mapper>

+ 46 - 6
kmall-admin/src/main/resources/mybatis/mapper/MkActivitiesCouponDao.xml

@@ -16,6 +16,11 @@
         <result property="createrSn" column="creater_sn"/>
         <result property="moderSn" column="moder_sn"/>
         <result property="updateTime" column="update_time"/>
+        <result property="activityType" column="activity_type"/>
+        <result property="brandId" column="brand_id"/>
+        <result property="categoryId" column="category_id"/>
+        <result property="brandName" column="brand_name"/>
+        <result property="categoryName" column="category_name"/>
     </resultMap>
 
 	<select id="queryObject" resultType="com.kmall.admin.entity.MkActivitiesCouponEntity">
@@ -31,7 +36,12 @@
 			`create_time`,
 			`creater_sn`,
 			`moder_sn`,
-			`update_time`
+			`update_time`,
+			`activity_type`,
+			`brand_id`,
+			`category_id`,
+			`brand_name`,
+			`category_name`
 		from mk_activities_coupon
 		where mac_id = #{id}
 	</select>
@@ -49,7 +59,12 @@
     		`create_time`,
     		`creater_sn`,
     		`moder_sn`,
-    		`update_time`
+    		`update_time`,
+			`activity_type`,
+			`brand_id`,
+			`category_id`,
+			`brand_name`,
+			`category_name`
 		from mk_activities_coupon
 		WHERE 1=1
 		<if test="name != null and name.trim() != ''">
@@ -100,7 +115,12 @@
 			`create_time`,
 			`creater_sn`,
 			`moder_sn`,
-			`update_time`)
+			`update_time`,
+			`activity_type`,
+			`brand_id`,
+			`category_id`,
+			`brand_name`,
+			`category_name`)
 		values(
 			#{goodsSn},
 			#{barcode},
@@ -112,7 +132,12 @@
 			#{createTime},
 			#{createrSn},
 			#{moderSn},
-			#{updateTime})
+			#{updateTime},
+			#{activityType},
+			#{brandId},
+			#{categoryId},
+			#{brandName},
+			#{categoryName})
 	</insert>
 
 	<update id="update" parameterType="com.kmall.admin.entity.MkActivitiesCouponEntity">
@@ -129,6 +154,11 @@
 			<if test="createrSn != null">`creater_sn` = #{createrSn}, </if>
 			<if test="moderSn != null">`moder_sn` = #{moderSn}, </if>
 			<if test="updateTime != null">`update_time` = #{updateTime}</if>
+			<if test="activityType != null">`activity_type` = #{activityType}</if>
+			<if test="brandId != null">`brand_id` = #{brandId}</if>
+			<if test="categoryId != null">`category_id` = #{categoryId}</if>
+			<if test="brandName != null">`brand_name` = #{brandName}</if>
+			<if test="categoryName != null">`category_name` = #{categoryName}</if>
 		</set>
 		where mac_id = #{macId}
 	</update>
@@ -157,7 +187,12 @@
 			`create_time`,
 			`creater_sn`,
 			`moder_sn`,
-			`update_time`
+			`update_time`,
+			`activity_type`,
+			`brand_id`,
+			`category_id`,
+			`brand_name`,
+			`category_name`
 		from mk_activities_coupon
 		where mka_id = #{mkaId}
 		and barcode = #{prodBarcode}
@@ -180,7 +215,12 @@
 			`create_time`,
 			`creater_sn`,
 			`moder_sn`,
-			`update_time`
+			`update_time`,
+			`activity_type`,
+			`brand_id`,
+			`category_id`,
+			`brand_name`,
+			`category_name`
 		from mk_activities_coupon
 		where coupon_sn = #{couponSn}
 		<if test="currentTime != null and currentTime.trim() != ''">

+ 116 - 7
kmall-admin/src/main/resources/mybatis/mapper/MkActivitiesFullGiftDao.xml

@@ -20,6 +20,12 @@
         <result property="createrSn" column="creater_sn"/>
         <result property="moderSn" column="moder_sn"/>
         <result property="updateTime" column="update_time"/>
+		<result property="fullGiftType" column="full_gift_type"/>
+		<result property="brandId" column="brand_id"/>
+		<result property="categoryId" column="category_id"/>
+		<result property="categoryName" column="category_name"/>
+		<result property="shopName" column="shop_name"/>
+		<result property="giftNumber" column="gift_number"/>
     </resultMap>
 
 	<select id="queryObject" resultType="com.kmall.admin.entity.MkActivitiesFullGiftEntity">
@@ -39,7 +45,13 @@
 			create_time,
 			creater_sn,
 			moder_sn,
-			update_time
+			update_time,
+			full_gift_type,
+			brand_id,
+			category_id,
+			category_name,
+			shop_name,
+			gift_number
 		from mk_activities_full_gift
 		where mafr_id = #{id}
 	</select>
@@ -61,7 +73,13 @@
     		create_time,
     		creater_sn,
     		moder_sn,
-    		update_time
+    		update_time,
+			full_gift_type,
+			brand_id,
+			category_id,
+			category_name,
+			shop_name,
+			gift_number
 		from mk_activities_full_gift
 		WHERE 1=1
 		<if test="name != null and name.trim() != ''">
@@ -116,7 +134,13 @@
 			create_time,
 			creater_sn,
 			moder_sn,
-			update_time)
+			update_time,
+			full_gift_type,
+			brand_id,
+			category_id,
+			category_name,
+			shop_name,
+			gift_number)
 		values(
 			#{productName},
 			#{shopSn},
@@ -132,7 +156,13 @@
 			#{createTime},
 			#{createrSn},
 			#{moderSn},
-			#{updateTime})
+			#{updateTime},
+			#{fullGiftType},
+			#{brandId},
+			#{categoryId},
+			#{categoryName},
+			#{shopName},
+			#{giftNumber})
 	</insert>
 
 	<update id="update" parameterType="com.kmall.admin.entity.MkActivitiesFullGiftEntity">
@@ -152,7 +182,13 @@
 			<if test="createTime != null">create_time = #{createTime}, </if>
 			<if test="createrSn != null">creater_sn = #{createrSn}, </if>
 			<if test="moderSn != null">moder_sn = #{moderSn}, </if>
-			<if test="updateTime != null">update_time = #{updateTime}</if>
+			<if test="updateTime != null">update_time = #{updateTime}, </if>
+			<if test="updateTime != null">full_gift_type = #{fullGiftType}, </if>
+			<if test="updateTime != null">brand_id = #{brandId}, </if>
+			<if test="updateTime != null">category_id = #{categoryId}, </if>
+			<if test="updateTime != null">category_name = #{categoryName}, </if>
+			<if test="shopName != null">shop_name = #{shopName}, </if>
+			<if test="giftNumber != null">gift_number = #{giftNumber}, </if>
 		</set>
 		where mafr_id = #{mafrId}
 	</update>
@@ -185,14 +221,87 @@
 			create_time,
 			creater_sn,
 			moder_sn,
-			update_time
+			update_time,
+			full_gift_type,
+			brand_id,
+			category_id,
+			category_name,
+			category_name,
+			shop_name,
+			gift_number
 		from mk_activities_full_gift
 		where
 			mka_id = #{mkaId}
 			<if test="brandName != 'all'">
 				and (barcode = #{prodBarcode} or product_brand = #{brandName})
 			</if>
-			and deadline &gt;= #{nowTime}
+			and deadline &lt;= #{nowTime}
+	</select>
+
+	<!--     /**
+     * 根据营销活动编号获取满赠活动信息
+     * @param mkaIdList     营销活动编号集合
+     * @return              满赠营销活动信息
+     */ -->
+	<select id="queryByMkaIdList" resultType="com.kmall.admin.entity.MkActivitiesFullGiftEntity">
+		select
+			mafr_id,
+			product_name,
+			shop_sn,
+			goods_sn,
+			barcode,
+			product_brand,
+			product_series,
+			qualified_amount,
+			gift_barcode,
+			gift_goods_sn,
+			mka_id,
+			deadline,
+			create_time,
+			creater_sn,
+			moder_sn,
+			update_time,
+			full_gift_type,
+			brand_id,
+			category_id,
+			category_name,
+			category_name,
+			shop_name,
+			gift_number
+		from mk_activities_full_gift
+		where mka_id in
+		<foreach collection="list" open="(" separator="," close=")" item="item">
+			#{item}
+		</foreach>
+	</select>
+
+	<select id="queryObjectByMkaIdAndStoreId" resultType="com.kmall.admin.entity.MkActivitiesFullGiftEntity">
+		select
+			mafr_id,
+			product_name,
+			shop_sn,
+			goods_sn,
+			barcode,
+			product_brand,
+			product_series,
+			qualified_amount,
+			gift_barcode,
+			gift_goods_sn,
+			mka_id,
+			deadline,
+			create_time,
+			creater_sn,
+			moder_sn,
+			update_time,
+			full_gift_type,
+			brand_id,
+			category_id,
+			category_name,
+			category_name,
+			shop_name,
+			gift_number
+		from mk_activities_full_gift
+		where mka_id = #{mkaId} and shop_sn = #{storeId}
 	</select>
 
 </mapper>

+ 21 - 1
kmall-admin/src/main/resources/mybatis/mapper/MkActivitiesPromotionDao.xml

@@ -204,8 +204,28 @@
 		and activity.mka_store_id = #{storeId}
 	</select>
 
+    <select id="queryListByMkaIdAndStoreId" resultType="com.kmall.admin.entity.MkActivitiesPromotionEntity">
+		select
+			map_id,
+			product_name,
+			activity_price,
+			shop_sn,
+			goods_sn,
+			barcode,
+			product_brand,
+			product_series,
+			mka_id,
+			deadline,
+			create_time,
+			creater_sn,
+			moder_sn,
+			update_time
+		from mk_activities_promotion
+		where mka_id = #{mkaId} and shop_sn = #{storeId}
+	</select>
+
 
-	<update id="updatePriceBySku" >
+    <update id="updatePriceBySku" >
 		update mk_activities_promotion set activity_price = #{updatePrice} where goods_sn = #{sku}
 		and mka_id = #{mkaId}
 	</update>

+ 26 - 0
kmall-admin/src/main/resources/mybatis/mapper/mk/MkActivitiesDao.xml

@@ -190,4 +190,30 @@
 			and mka_topic = #{topic}
 			and mka_status = 1
 	</select>
+
+	<!-- 查询满赠的活动 -->
+    <select id="queryByNowByMz" resultType="com.kmall.admin.entity.mk.MkActivitiesEntity">
+		select
+			mka_id,
+			mka_topic,
+			merch_sn,
+			third_merch_sn,
+			mka_store_id,
+			mka_status,
+			mka_start_time,
+			mkd_end_time,
+			mka_end_early,
+			mkd_end_early_time,
+			create_time,
+			creater_sn,
+			update_time,
+			moder_sn
+		from mk_activities ma
+		where
+			mka_store_id = #{storeId}
+			and mka_start_time &lt; #{currentTime}
+			and mkd_end_time &gt; #{currentTime}
+			and mka_topic = 'mz'
+			and mka_status = 1
+	</select>
 </mapper>

+ 30 - 6
kmall-admin/src/main/webapp/WEB-INF/page/mk/mkactivitiesfullgift.html

@@ -39,27 +39,51 @@
 
     <Card v-show="!showList">
         <p slot="title">{{title}}</p>
-		<i-form ref="formValidate" :model="mkActivitiesFullGift" :rules="ruleValidate" :label-width="80">
+		<i-form ref="formValidate" :model="mkActivitiesFullGift" :rules="ruleValidate" :label-width="120">
             <!--<Form-item label="产品中文名" prop="productName">
                 <i-input v-model="mkActivitiesFullGift.productName" placeholder="产品中文名"/>
             </Form-item>-->
-            <Form-item label="商品编码" prop="goodsSn">
+            <!--<Form-item label="商品编码" prop="goodsSn">
                 <i-input v-model="mkActivitiesFullGift.goodsSn" placeholder="商品编码"/>
             </Form-item>
             <Form-item label="条形码" prop="barcode">
                 <i-input v-model="mkActivitiesFullGift.barcode" placeholder="条形码"/>
+            </Form-item>-->
+            <Form-item label="注意:">
+                <p style="color: red; font-size: 20px">品牌与分类只能选其一,如两者都填写,最终按满赠类型进行判断</p>
+            </Form-item>
+            <Form-item label="门店ID" prop="shopSn">
+                <i-input v-model="mkActivitiesFullGift.shopSn" placeholder="门店ID"/>
+            </Form-item>
+            <Form-item label="门店名称" prop="shopName">
+                <i-input v-model="mkActivitiesFullGift.shopName" placeholder="门店名称"/>
+            </Form-item>
+            <Form-item label="商品品牌ID" prop="brandId">
+                <i-input v-model="mkActivitiesFullGift.brandId" placeholder="商品品牌ID"/>
             </Form-item>
-            <Form-item label="商品品牌" prop="productBrand">
-                <i-input v-model="mkActivitiesFullGift.productBrand" placeholder="商品品牌"/>
+            <Form-item label="商品品牌名称" prop="productBrand">
+                <i-input v-model="mkActivitiesFullGift.productBrand" placeholder="商品品牌名称"/>
+            </Form-item>
+            <Form-item label="商品分类ID" prop="categoryId">
+                <i-input v-model="mkActivitiesFullGift.categoryId" placeholder="商品分类ID"/>
+            </Form-item>
+            <Form-item label="商品分类名称" prop="categoryName">
+                <i-input v-model="mkActivitiesFullGift.categoryName" placeholder="商品分类名称"/>
             </Form-item>
             <!--<Form-item label="商品系列" prop="productSeries">
                 <i-input v-model="mkActivitiesFullGift.productSeries" placeholder="商品系列"/>
             </Form-item>-->
+            <Form-item label="满赠活动类型" prop="fullGiftType">
+                <i-input v-model="mkActivitiesFullGift.fullGiftType" placeholder="满赠活动类型,0:按品牌,1:按分类,2:按门店"/>
+            </Form-item>
             <Form-item label="满足条件金额" prop="qualifiedAmount">
                 <i-input v-model="mkActivitiesFullGift.qualifiedAmount" placeholder="满足条件金额"/>
             </Form-item>
-            <Form-item label="赠品条码" prop="giftBarcode">
-                <i-input v-model="mkActivitiesFullGift.giftBarcode" placeholder="赠品条码"/>
+            <Form-item label="赠品商品条码" prop="giftBarcode">
+                <i-input v-model="mkActivitiesFullGift.giftBarcode" placeholder="赠品商品条码"/>
+            </Form-item>
+            <Form-item label="赠品商品编码" prop="giftGoodsSn">
+                <i-input v-model="mkActivitiesFullGift.giftGoodsSn" placeholder="赠品商品编码"/>
             </Form-item>
             <Form-item label="截止日期" prop="deadline">
                 <i-input v-model="mkActivitiesFullGift.deadline" placeholder="截止日期 yyyy-mm-dd"/>

+ 27 - 3
kmall-admin/src/main/webapp/WEB-INF/page/sale/sale.html

@@ -156,7 +156,7 @@
                             <img style="height: 400px;width: 400px;" :src="goods.primaryPicUrl" class="img-rounded"/>
                             <h1 style="margin: 8px;"><strong>{{goods.name}}</strong></h1>
                             <p style="margin: 8px;">单价: <strong>{{goods.retailPrice}}</strong> /元</p>
-                            <p style="margin: 8px;">税费: <strong>{{goods.goodstaxes}}</strong> /元</p>
+                            <p style="margin: 8px;">优惠前税费: <strong>{{goods.goodstaxes}}</strong> /元</p>
                             <p style="margin: 8px;">规格: {{goods.specification}}</p>
                             <p style="margin: 8px;">条形码: {{goods.prodBarcode}}</p>
                             <!--<span style="margin: 8px;">商品描述: {{goods.goodsDesc}}</span>-->
@@ -217,6 +217,7 @@
                         <i-button type="error" @click="clearGoodsList" class="goods-button"><i class="fa fa-pencil-square-o"></i>&nbsp;清空</i-button>
                         <i-button data-toggle="modal" @click="pendingOrder" class="goods-button" ><i class="fa fa-pencil-square-o"></i>&nbsp;订单挂起</i-button>
                         <i-button data-toggle="modal" @click="toResumePending" class="goods-button" ><i class="fa fa-pencil-square-o"></i>&nbsp;恢复挂起</i-button>
+                        <i-button data-toggle="modal" @click="calculateOrderPrice" type="primary" class="goods-button" ><i class="fa fa-pencil-square-o"></i>&nbsp;计算优惠后价格</i-button>
                         <i-button data-toggle="modal" @click="toOrderSubmit" type="primary" class="goods-button" ><i class="fa fa-pencil-square-o"></i>&nbsp;提交订单</i-button>
 
 <!--                        45636914-->
@@ -247,10 +248,10 @@
                                     </div>
                                     <div class="modal-body">
                                         <form>
-                                            <div class="form-group">
+                                            <!--<div class="form-group">
                                                 <label for="customPhone" class="control-label">会员码:</label>
                                                 <input autocomplete="off" type="text" class="form-control" ref="couponBarCode" id="couponBarCode" @blur="customPhoneBlur" />
-                                            </div>
+                                            </div>-->
                                             <div class="form-group">
                                                 <label for="customPhone" class="control-label">手机号:</label>
                                                 <input autocomplete="off" type="text" class="form-control" ref="customPhone" id="customPhone" @blur="customPhoneBlur" />
@@ -297,6 +298,29 @@
                             </div>
                         </div>
 
+                        <div class="modal fade" id="calculateOrderPriceDialog"  role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+                            <div class="modal-dialog">
+                                <div class="modal-content">
+                                    <div class="modal-header">
+                                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+                                        <h4 class="modal-title" id="calculateOrderPriceModalLabel">录入会员码</h4>
+                                    </div>
+                                    <div class="modal-body">
+                                        <form>
+                                            <div class="form-group">
+                                                <label for="customPhone" class="control-label">会员码:</label>
+                                                <input autocomplete="off" type="text" class="form-control" ref="couponBarCode" id="couponBarCode" @blur="customPhoneBlur" />
+                                            </div>
+                                        </form>
+                                    </div>
+                                    <div class="modal-footer">
+                                        <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
+                                        <button type="button" class="btn btn-primary" @click="calculateOrderPriceSubmit">计算优惠价</button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+
                         <!--付款码 -->
                         <div class="modal fade" id="payModal"  role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                             <div class="modal-dialog">

+ 10 - 4
kmall-admin/src/main/webapp/js/mk/mkactivitiesfullgift.js

@@ -23,13 +23,19 @@ $(function () {
         datatype: "json",
         colModel: [
 			{label: 'mafrId', name: 'mafrId', index: 'mafr_id', key: true, hidden: true},
-			{label: '产品中文名', name: 'productName', index: 'product_name', width: 80, align: 'center'},
+			/*{label: '产品中文名', name: 'productName', index: 'product_name', width: 80, align: 'center'},
 			{label: '商品编码', name: 'goodsSn', index: 'goods_sn', width: 80, align: 'center'},
-			{label: '条形码', name: 'barcode', index: 'barcode', width: 80, align: 'center'},
-			{label: '商品品牌', name: 'productBrand', index: 'product_brand', width: 80, align: 'center'},
+			{label: '条形码', name: 'barcode', index: 'barcode', width: 80, align: 'center'},*/
+			{label: '门店ID', name: 'shopSn', index: 'shop_sn', width: 80, align: 'center'},
+			{label: '门店名称', name: 'shopName', index: 'shop_name', width: 80, align: 'center'},
+			{label: '商品品牌ID', name: 'brandId', index: 'brand_id', width: 80, align: 'center'},
+			{label: '商品品牌名称', name: 'productBrand', index: 'product_brand', width: 80, align: 'center'},
+			{label: '商品分类ID', name: 'categoryId', index: 'category_id', width: 80, align: 'center'},
+			{label: '商品分类名称', name: 'categoryName', index: 'category_name', width: 80, align: 'center'},
 			// {label: '商品系列', name: 'productSeries', index: 'product_series', width: 80, align: 'center'},
 			{label: '满足条件金额', name: 'qualifiedAmount', index: 'qualified_amount', width: 80, align: 'center'},
-			{label: '赠品条码', name: 'giftBarcode', index: 'gift_barcode', width: 80, align: 'center'},
+			{label: '赠品商品条码', name: 'giftBarcode', index: 'gift_barcode', width: 80, align: 'center'},
+			{label: '赠品商品编码', name: 'giftGoodsSn', index: 'gift_goods_sn', width: 80, align: 'center'},
 			{label: '截止日期', name: 'deadline', index: 'deadline', width: 80, align: 'center'}],
 		viewrecords: true,
 		postData: {'mkaId': vm.mkaId},

+ 72 - 0
kmall-admin/src/main/webapp/js/sale/sale.js

@@ -590,6 +590,8 @@ let vm = new Vue({
 
         canRefund:true,
         openSku:false,
+        // 保存商品详情的list
+        calGoodsList : []
 
     },
     watch: {
@@ -697,6 +699,9 @@ let vm = new Vue({
                             calculateGoodsPrice(r);
                             handle(r.goodsDetails,"add");
                             vm.openSku = false;
+                            var data = Object.assign({}, JSON.parse(JSON.stringify(r.goodsDetails)));
+                            console.log("商品详情===>" + JSON.stringify(data));
+                            vm.calGoodsList.push(data);
                             //此时必须异步执行滚动条滑动至底部
                             setTimeout(()=>{
                                 overflowLi.scrollTop = overflowLi.scrollHeight;
@@ -719,6 +724,9 @@ let vm = new Vue({
                         calculateGoodsPrice(r);
                         handle(r.goodsDetails,"add");
                         vm.openSku = false;
+                        var data = Object.assign({}, JSON.parse(JSON.stringify(r.goodsDetails)));
+                        console.log("商品详情===>" + JSON.stringify(data));
+                        vm.calGoodsList.push(data);
                         //此时必须异步执行滚动条滑动至底部
                         setTimeout(()=>{
                             overflowLi.scrollTop = overflowLi.scrollHeight;
@@ -926,6 +934,24 @@ let vm = new Vue({
                 vm.$refs.couponSn.value = "";
             this.userInfo.couponSn = "";
         },
+        // 点击计算优惠价按钮,弹出输入框
+        calculateOrderPrice : function () {
+            if (this.calGoodsList.length == 0) {
+                alert("请选择商品");
+                return;
+            }
+            $("#calculateOrderPriceDialog").modal('show');
+
+        },
+        // 计算优惠价格,返回订单详情数据
+        calculateOrderPriceSubmit : function () {
+            console.log("11111");
+            var couponBarCode = vm.$refs.couponBarCode;
+            if (couponBarCode === null || couponBarCode === '') {
+                alert("无会员码,不能参加积分抵扣活动!\n计算中...");
+            }
+            calculateOrderPrice();
+        },
         // 提交订单
         submitOrder:function(){
             vm.parCode = this.$refs.payCode.currentValue
@@ -1868,8 +1894,10 @@ function handle(goodsDetails,operatorType){
 
     if("minus" == operatorType){
         vm.totalCount = vm.totalCount - 1;
+        vm.goodsList[vm.index].sellVolume -= 1;
     }else{
         vm.totalCount = vm.totalCount + 1;
+        vm.goodsList[vm.index].sellVolume += 1;
     }
 
     if(vm.reduceMoney > 0){
@@ -1973,5 +2001,49 @@ function toRefund(){
         });
     })
 }
+// 计算当前购物栏商品优惠价格
+function calculateOrderPrice() {
+    vm.machineCode = sessionStorage.getItem("machineCode");
+    var cmbCity = $('#cmbCity').val();
+    var cmbProvince = $('#cmbProvince').val();
+    var cmbArea = $('#cmbArea').val();
+    var addrUser = $('#addrUser').val();
+    addrUser = cmbProvince+cmbCity+cmbArea+addrUser;
+    console.log(vm.machineCode);
+    var param = {
+        'storeId': sessionStorage.getItem("storeId"),
+        'goodsList' : vm.calGoodsList
+    };
+
+    console.log("请求参数===>" + JSON.stringify(param));
+
+    $.ajax({
+        type: "POST",
+        url: "../order/calculateOrderDiscountPrice",
+        contentType: "application/json",
+        data: JSON.stringify(param),
+        success: function (r) {
+            if (r.code == 0) {
+                let calGoodsList = r.goodsList;
+                // 更新购物栏中数据
+                console.log("返回====>" + JSON.stringify(r));
+                console.log("计算前数据===>" + JSON.stringify(vm.goodsList));
+                vm.goodsList.clear();
+                calGoodsList.forEach(goods => {
+                    goods.sellVolume = $("#")
+                    vm.goodsList.push(goods);
+                });
+                console.log("计算后数据===>" + JSON.stringify(calGoodsList));
+                console.log("替换后数据===>" + JSON.stringify(vm.goodsList));
+
+                $("#calculateOrderPriceDialog").modal('hide');
+            } else if (r.code == 500) {
+                alert(r.msg)
+            } else {
+                alert("计算失败,请联系管理员");
+            }
+        }
+    });
+}
 
 

+ 1 - 1
kmall-api/pom.xml

@@ -3,7 +3,7 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <artifactId>kmall-pt-general</artifactId>
+        <artifactId>kmall-haikong</artifactId>
         <groupId>com.kmall</groupId>
         <version>3.1.0</version>
     </parent>

+ 1 - 1
kmall-common/pom.xml

@@ -3,7 +3,7 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <artifactId>kmall-pt-general</artifactId>
+        <artifactId>kmall-haikong</artifactId>
         <groupId>com.kmall</groupId>
         <version>3.1.0</version>
     </parent>

+ 1 - 1
kmall-framework/pom.xml

@@ -3,7 +3,7 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <artifactId>kmall-pt-general</artifactId>
+        <artifactId>kmall-haikong</artifactId>
         <groupId>com.kmall</groupId>
         <version>3.1.0</version>
     </parent>

+ 1 - 1
kmall-gen/pom.xml

@@ -3,7 +3,7 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <artifactId>kmall-pt-general</artifactId>
+        <artifactId>kmall-haikong</artifactId>
         <groupId>com.kmall</groupId>
         <version>3.1.0</version>
     </parent>

+ 1 - 1
kmall-manager/pom.xml

@@ -3,7 +3,7 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <artifactId>kmall-pt-general</artifactId>
+        <artifactId>kmall-haikong</artifactId>
         <groupId>com.kmall</groupId>
         <version>3.1.0</version>
     </parent>

+ 1 - 1
kmall-schedule/pom.xml

@@ -3,7 +3,7 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <artifactId>kmall-pt-general</artifactId>
+        <artifactId>kmall-haikong</artifactId>
         <groupId>com.kmall</groupId>
         <version>3.1.0</version>
     </parent>