1
0
Pārlūkot izejas kodu

Merge branch 'master' of hyq/kmall-pt into master

黄亚琴 6 gadi atpakaļ
vecāks
revīzija
89e0277186
77 mainītis faili ar 2408 papildinājumiem un 642 dzēšanām
  1. 13 0
      kmall-admin/src/main/java/com/kmall/admin/controller/ProductStoreRelaController.java
  2. 34 0
      kmall-admin/src/main/java/com/kmall/admin/controller/ThirdMerchantBizController.java
  3. 1 1
      kmall-admin/src/main/java/com/kmall/admin/dao/ProductDao.java
  4. 9 0
      kmall-admin/src/main/java/com/kmall/admin/entity/GoodsEntity.java
  5. 43 0
      kmall-admin/src/main/java/com/kmall/admin/entity/ProductStoreRelaEntity.java
  6. 22 0
      kmall-admin/src/main/java/com/kmall/admin/entity/ThirdMerchantBizEntity.java
  7. 1 1
      kmall-admin/src/main/java/com/kmall/admin/service/ProductService.java
  8. 1 0
      kmall-admin/src/main/java/com/kmall/admin/service/ThirdMerchantBizService.java
  9. 32 21
      kmall-admin/src/main/java/com/kmall/admin/service/impl/GoodsServiceImpl.java
  10. 42 8
      kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java
  11. 2 2
      kmall-admin/src/main/java/com/kmall/admin/service/impl/ProductServiceImpl.java
  12. 40 10
      kmall-admin/src/main/java/com/kmall/admin/service/impl/ProductStoreRelaServiceImpl.java
  13. 4 1
      kmall-admin/src/main/java/com/kmall/admin/service/impl/ThirdMerchantBizServiceImpl.java
  14. 19 0
      kmall-admin/src/main/java/com/kmall/admin/utils/XBasicDataSource.java
  15. 5 2
      kmall-admin/src/main/resources/mybatis/mapper/GoodsDao.xml
  16. 16 4
      kmall-admin/src/main/resources/mybatis/mapper/ProductDao.xml
  17. 15 3
      kmall-admin/src/main/resources/mybatis/mapper/ProductStoreRelaDao.xml
  18. 18 2
      kmall-admin/src/main/resources/mybatis/mapper/ThirdMerchantBizDao.xml
  19. 8 0
      kmall-admin/src/main/resources/spring/spring-jdbc.xml
  20. 13 8
      kmall-admin/src/main/webapp/WEB-INF/page/shop/goods.html
  21. 19 5
      kmall-admin/src/main/webapp/WEB-INF/page/shop/storeProductStock.html
  22. 20 0
      kmall-admin/src/main/webapp/WEB-INF/page/shop/thirdmerchantbiz.html
  23. 1 6
      kmall-admin/src/main/webapp/WEB-INF/web.xml
  24. 47 1
      kmall-admin/src/main/webapp/js/shop/goods.js
  25. 37 29
      kmall-admin/src/main/webapp/js/shop/storeProductStock.js
  26. 40 16
      kmall-admin/src/main/webapp/js/shop/thirdmerchantbiz.js
  27. 111 15
      kmall-api/src/main/java/com/kmall/api/api/ApiCartController.java
  28. 7 2
      kmall-api/src/main/java/com/kmall/api/api/ApiFootprintController.java
  29. 81 9
      kmall-api/src/main/java/com/kmall/api/api/ApiGoodsController.java
  30. 5 28
      kmall-api/src/main/java/com/kmall/api/api/ApiIndexController.java
  31. 7 0
      kmall-api/src/main/java/com/kmall/api/dao/ApiGoodsMapper.java
  32. 6 0
      kmall-api/src/main/java/com/kmall/api/dao/ApiProductMapper.java
  33. 20 0
      kmall-api/src/main/java/com/kmall/api/dao/ApiThirdMerchantBizMapper.java
  34. 20 0
      kmall-api/src/main/java/com/kmall/api/entity/CartVo.java
  35. 49 1
      kmall-api/src/main/java/com/kmall/api/entity/GoodsVo.java
  36. 203 0
      kmall-api/src/main/java/com/kmall/api/entity/ThirdMerchantBizVo.java
  37. 81 18
      kmall-api/src/main/java/com/kmall/api/service/ApiOrderService.java
  38. 62 0
      kmall-api/src/main/java/com/kmall/api/service/ApiThirdMerchantBizService.java
  39. 32 4
      kmall-api/src/main/resources/mybatis/mapper/ApiCartMapper.xml
  40. 50 10
      kmall-api/src/main/resources/mybatis/mapper/ApiGoodsMapper.xml
  41. 5 3
      kmall-api/src/main/resources/mybatis/mapper/ApiProductMapper.xml
  42. 183 0
      kmall-api/src/main/resources/mybatis/mapper/ApiThirdMerchantBizMapper.xml
  43. 11 0
      kmall-common/pom.xml
  44. 32 0
      kmall-common/src/main/java/com/kmall/common/constant/Dict.java
  45. 45 0
      kmall-common/src/main/java/com/kmall/common/listener/ContextFinalizer.java
  46. 45 0
      kmall-common/src/main/java/com/kmall/common/listener/QuartzContextListener.java
  47. 8 6
      kmall-framework/src/main/webapp/WEB-INF/web.xml
  48. 8 0
      kmall-framework/src/test/resources/applicationContext-test.xml
  49. 2 0
      kmall-schedule/src/main/java/com/kmall/schedule/dao/QzOrderMapper.java
  50. 38 32
      kmall-schedule/src/main/java/com/kmall/schedule/service/QzOrderService.java
  51. 3 0
      kmall-schedule/src/main/resources/kmall-scheduler.xml
  52. 24 8
      kmall-schedule/src/main/resources/mybatis/mapper/QzOrderMapper.xml
  53. 1 1
      pom.xml
  54. 2 1
      wx-mall/app.js
  55. 1 1
      wx-mall/app.wxss
  56. 64 20
      wx-mall/pages/cart/cart.js
  57. 4 3
      wx-mall/pages/cart/cart.wxml
  58. 1 1
      wx-mall/pages/cart/cart.wxss
  59. 79 14
      wx-mall/pages/catalog/catalog.js
  60. 4 1
      wx-mall/pages/catalog/catalog.json
  61. 27 24
      wx-mall/pages/catalog/catalog.wxml
  62. 1 1
      wx-mall/pages/catalog/catalog.wxss
  63. 87 57
      wx-mall/pages/category/category.js
  64. 3 2
      wx-mall/pages/category/category.json
  65. 26 5
      wx-mall/pages/category/category.wxml
  66. 10 2
      wx-mall/pages/category/category.wxss
  67. 39 16
      wx-mall/pages/goods/goods.js
  68. 6 3
      wx-mall/pages/goods/goods.wxml
  69. 1 1
      wx-mall/pages/goods/goods.wxss
  70. 40 9
      wx-mall/pages/hotGoods/hotGoods.js
  71. 1 0
      wx-mall/pages/hotGoods/hotGoods.wxml
  72. 1 1
      wx-mall/pages/hotGoods/hotGoods.wxss
  73. 125 22
      wx-mall/pages/index/index.js
  74. 9 3
      wx-mall/pages/index/index.wxml
  75. 200 179
      wx-mall/pages/search/search.js
  76. 21 7
      wx-mall/pages/ucenter/addressAdd/addressAdd.js
  77. 15 12
      wx-mall/pages/ucenter/order/order.js

+ 13 - 0
kmall-admin/src/main/java/com/kmall/admin/controller/ProductStoreRelaController.java

@@ -2,12 +2,16 @@ package com.kmall.admin.controller;
 
 import com.kmall.admin.entity.ProductStoreRelaEntity;
 import com.kmall.admin.entity.StoreEntity;
+import com.kmall.admin.entity.ThirdMerchantBizEntity;
 import com.kmall.admin.service.ProductStoreRelaService;
 import com.kmall.admin.service.StoreService;
+import com.kmall.admin.service.ThirdMerchantBizService;
 import com.kmall.admin.utils.ParamUtils;
+import com.kmall.common.constant.Dict;
 import com.kmall.common.utils.PageUtils;
 import com.kmall.common.utils.Query;
 import com.kmall.common.utils.R;
+import com.kmall.common.utils.StringUtils;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
@@ -51,6 +55,15 @@ public class ProductStoreRelaController {
         Query query = new Query(params);
 
         List<ProductStoreRelaEntity> productStoreRelaList = productStoreRelaService.queryList(query);
+        for (ProductStoreRelaEntity pro: productStoreRelaList) {
+            if(org.apache.commons.lang3.StringUtils.isNotEmpty(pro.getIsStockShare())) {
+                if (pro.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_00.getItem())) {
+                    if(pro.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_1.getItem())) {
+                        pro.setStockNum(pro.getGoodsNumber());
+                    }
+                }
+            }
+        }
         int total = productStoreRelaService.queryTotal(query);
 
         PageUtils pageUtil = new PageUtils(productStoreRelaList, total, query.getLimit(), query.getPage());

+ 34 - 0
kmall-admin/src/main/java/com/kmall/admin/controller/ThirdMerchantBizController.java

@@ -3,6 +3,7 @@ package com.kmall.admin.controller;
 import java.util.List;
 import java.util.Map;
 
+import com.google.common.collect.ImmutableBiMap;
 import com.kmall.admin.entity.StoreEntity;
 import com.kmall.admin.entity.ThirdMerchantBizEntity;
 import com.kmall.admin.service.StoreService;
@@ -70,6 +71,17 @@ public class ThirdMerchantBizController {
 
         return R.ok().put("thirdMerchantBiz", thirdMerchantBiz);
     }
+    /**
+     * 查看信息
+     */
+    @RequestMapping("/infoByCode")
+    @ResponseBody
+    public R infoByCode(@RequestParam Map<String, Object> params) {
+        String thirdMerchantCode = (String) params.get("thirdMerchantCode");
+        ThirdMerchantBizEntity thirdMerchantBiz = thirdMerchantBizService.getThirdMerchangByCode(thirdMerchantCode);
+
+        return R.ok().put("thirdMerchantBiz", thirdMerchantBiz);
+    }
 
     /**
      * 保存
@@ -85,6 +97,17 @@ public class ThirdMerchantBizController {
         }else {
             throw new RRException("登陆用户失效,请重新登陆!");
         }
+        Map<String, Object> valideDate = MapBeanUtil.fromObject(thirdMerchantBiz);
+        ImmutableBiMap.Builder builder = new ImmutableBiMap.Builder();
+        builder.put("merchSn", "商户编号");
+        builder.put("thirdPartyMerchCode", "第三方商户代码");
+        builder.put("thirdPartyMerchName", "第三方商户名称");
+        builder.put("isStockShare", "库存是否共享");
+        builder.put("isStoreUserShare", "门店用户是否共享");
+        R r = ValidatorUtil.isEmpty(builder.build(), valideDate);
+        if (Integer.valueOf(r.get("code").toString()) != 0) {
+            throw new RRException(r.get("msg").toString());
+        }
         thirdMerchantBizService.save(thirdMerchantBiz);
 
         return R.ok();
@@ -104,6 +127,17 @@ public class ThirdMerchantBizController {
         }else {
             throw new RRException("登陆用户失效,请重新登陆!");
         }
+        Map<String, Object> valideDate = MapBeanUtil.fromObject(thirdMerchantBiz);
+        ImmutableBiMap.Builder builder = new ImmutableBiMap.Builder();
+        builder.put("merchSn", "商户编号");
+        builder.put("thirdPartyMerchCode", "第三方商户代码");
+        builder.put("thirdPartyMerchName", "第三方商户名称");
+//        builder.put("isStockShare", "库存是否共享");
+//        builder.put("isStoreUserShare", "门店用户是否共享");
+        R r = ValidatorUtil.isEmpty(builder.build(), valideDate);
+        if (Integer.valueOf(r.get("code").toString()) != 0) {
+            throw new RRException(r.get("msg").toString());
+        }
         thirdMerchantBizService.update(thirdMerchantBiz);
 
         return R.ok();

+ 1 - 1
kmall-admin/src/main/java/com/kmall/admin/dao/ProductDao.java

@@ -27,7 +27,7 @@ public interface ProductDao extends BaseDao<ProductEntity> {
      * @param goodsId
      * @return
      */
-    ProductEntity queryObjectByGoodsId(@Param("goodsId") String goodsId);
+    ProductEntity queryObjectByGoodsIdAndStoreId(@Param("goodsId") String goodsId,@Param("storeId")String storeId);
 
 //    /**
 //     * 根据编码查询产品

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

@@ -180,6 +180,15 @@ public class GoodsEntity implements Serializable {
     private String merchSn;
     private String merchName;
     private String thirdPartyMerchCode;
+    private String isStockShare;
+
+    public String getIsStockShare() {
+        return isStockShare;
+    }
+
+    public void setIsStockShare(String isStockShare) {
+        this.isStockShare = isStockShare;
+    }
 
     public String getThirdPartyMerchCode() {
         return thirdPartyMerchCode;

+ 43 - 0
kmall-admin/src/main/java/com/kmall/admin/entity/ProductStoreRelaEntity.java

@@ -98,8 +98,51 @@ public class ProductStoreRelaEntity implements Serializable {
     //属性类别
     private Integer attributeCategory;
 
+    /**
+     * 第三方商户代码
+     */
+    private String thirdPartyMerchCode;
+
+    private Integer goodsNumber;
+
+    private String isStockShare;
+
+    private Integer goodsSellVolume;
+
     List<GoodsAttributeEntity> attributeEntityList = new ArrayList<>();
 
+    public Integer getGoodsSellVolume() {
+        return goodsSellVolume;
+    }
+
+    public void setGoodsSellVolume(Integer goodsSellVolume) {
+        this.goodsSellVolume = goodsSellVolume;
+    }
+
+    public String getIsStockShare() {
+        return isStockShare;
+    }
+
+    public void setIsStockShare(String isStockShare) {
+        this.isStockShare = isStockShare;
+    }
+
+    public Integer getGoodsNumber() {
+        return goodsNumber;
+    }
+
+    public void setGoodsNumber(Integer goodsNumber) {
+        this.goodsNumber = goodsNumber;
+    }
+
+    public String getThirdPartyMerchCode() {
+        return thirdPartyMerchCode;
+    }
+
+    public void setThirdPartyMerchCode(String thirdPartyMerchCode) {
+        this.thirdPartyMerchCode = thirdPartyMerchCode;
+    }
+
     public Integer getFreightId() {
         return freightId;
     }

+ 22 - 0
kmall-admin/src/main/java/com/kmall/admin/entity/ThirdMerchantBizEntity.java

@@ -28,6 +28,12 @@ public class ThirdMerchantBizEntity implements Serializable {
      * 第三方商户名称
      */
     private String thirdPartyMerchName;
+
+    private String isStockShare;
+
+    private String isStoreUserShare;
+
+
     /**
      * 是否有效,0:有效,1:无效
      */
@@ -53,6 +59,22 @@ public class ThirdMerchantBizEntity implements Serializable {
      */
     private Date tstm;
 
+    public String getIsStoreUserShare() {
+        return isStoreUserShare;
+    }
+
+    public void setIsStoreUserShare(String isStoreUserShare) {
+        this.isStoreUserShare = isStoreUserShare;
+    }
+
+    public String getIsStockShare() {
+        return isStockShare;
+    }
+
+    public void setIsStockShare(String isStockShare) {
+        this.isStockShare = isStockShare;
+    }
+
     public String getMerchSn() {
         return merchSn;
     }

+ 1 - 1
kmall-admin/src/main/java/com/kmall/admin/service/ProductService.java

@@ -28,7 +28,7 @@ public interface ProductService {
      * @param goodsId
      * @return 实体
      */
-    ProductEntity queryObjectByGoodsId(String goodsId);
+    ProductEntity queryObjectByGoodsIdAndStoreId(String goodsId,String storeId);
 
     /**
      * 分页查询

+ 1 - 0
kmall-admin/src/main/java/com/kmall/admin/service/ThirdMerchantBizService.java

@@ -22,6 +22,7 @@ public interface ThirdMerchantBizService {
      */
     ThirdMerchantBizEntity queryObject(Integer thirdMerchSn);
 
+    ThirdMerchantBizEntity getThirdMerchangByCode(String thirdMerchCode);
     /**
      * 分页查询
      *

+ 32 - 21
kmall-admin/src/main/java/com/kmall/admin/service/impl/GoodsServiceImpl.java

@@ -9,6 +9,7 @@ import com.kmall.admin.service.GoodsService;
 import com.kmall.common.constant.Dict;
 import com.kmall.common.entity.SysUserEntity;
 import com.kmall.common.utils.*;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -319,6 +320,9 @@ public class GoodsServiceImpl implements GoodsService {
         goods.setUpdateUserId(user.getUserId());
         goods.setUpdateTime(new Date());
         goods.setModTime(new Date());
+        if(goods.getGoodsNumber()==null){
+            goods.setGoodsNumber(0);
+        }
 
         // 修改商品
         goodsDao.update(goods);
@@ -419,15 +423,23 @@ public class GoodsServiceImpl implements GoodsService {
         }*/
 
         // 修改产品
-        ProductEntity product = productDao.queryObjectByGoodsId(String.valueOf(goods.getId()));
+        ProductEntity product = productDao.queryObjectByGoodsIdAndStoreId(String.valueOf(goods.getId()),"");
 
-        GoodsSpecificationEntity goodsSpecification = new GoodsSpecificationEntity();
+        GoodsSpecificationEntity goodsSpecification = null;
         // 保税商品,普通货物暂不添加商品规格
         if (!Dict.orderBizType.item_11.getItem().equals(goods.getGoodsBizType())) {
             // 添加商品规格
             goodsSpecification = goodsSpecificationDao.queryByGoodsId(goods.getId());
-            goodsSpecification.setValue(goods.getCiqProdModel());
-            goodsSpecificationDao.update(goodsSpecification);
+            if(goodsSpecification != null) {
+                goodsSpecification.setValue(goods.getCiqProdModel());
+                goodsSpecificationDao.update(goodsSpecification);
+            }else{
+                goodsSpecification = new GoodsSpecificationEntity();
+                goodsSpecification.setGoodsId(goods.getId());
+                goodsSpecification.setValue(goods.getCiqProdModel());
+                goodsSpecification.setSpecificationId(1);
+                goodsSpecificationDao.save(goodsSpecification);
+            }
 
             if(product == null){
                 product = new ProductEntity();
@@ -762,10 +774,10 @@ public class GoodsServiceImpl implements GoodsService {
 //                        }
 //                    }
                     // 修改产品
-                    ProductEntity product = productDao.queryObjectByGoodsId(String.valueOf(goodsEntity.getId()));
+                    ProductEntity product = productDao.queryObjectByGoodsIdAndStoreId(String.valueOf(goodsEntity.getId()), "");
 
                     GoodsSpecificationEntity goodsSpecification = new GoodsSpecificationEntity();
-                    // 保税商品,普通货物暂不添加商品规格
+                    // 普通货物暂不添加商品规格
                     if (!Dict.orderBizType.item_11.getItem().equals(goodsDto.getGoodsBizType())) {
                         // 添加商品规格
                         GoodsSpecificationEntity specificationEntity = goodsSpecificationDao.queryByGoodsId(goodsEntity.getId());
@@ -779,21 +791,20 @@ public class GoodsServiceImpl implements GoodsService {
                             goodsSpecification.setId(specificationEntity.getId());
                             goodsSpecificationDao.update(goodsSpecification);
                         }
-                        product.setGoodsSpecificationNameValue(goodsSpecification.getValue());
-                        product.setGoodsSpecificationIds(goodsSpecification.getId().toString());
-                    }
-
-                    if(product == null){
-                        product = new ProductEntity();
-                        product.setGoodsSn(goodsDto.getGoodsSn());
-                        product.setGoodsId(goodsEntity.getId());
-                        product.setGoodsDefault(0);
-                        product.setGoodsNumber(goodsEntity.getGoodsNumber());
-                        productDao.save(product);
-                    }else{
-                        product.setGoodsSpecificationIds(goodsSpecification.getId().toString());
-                        product.setGoodsSpecificationNameValue(goodsSpecification.getValue());
-                        productDao.update(product);
+                        if(product == null){
+                            product = new ProductEntity();
+                            product.setGoodsSn(goodsDto.getGoodsSn());
+                            product.setGoodsId(goodsEntity.getId());
+                            product.setGoodsDefault(0);
+                            product.setGoodsNumber(goodsEntity.getGoodsNumber());
+                            product.setGoodsSpecificationNameValue(goodsSpecification.getValue());
+                            product.setGoodsSpecificationIds(goodsSpecification.getId().toString());
+                            productDao.save(product);
+                        }else{
+                            product.setGoodsSpecificationIds(goodsSpecification.getId().toString());
+                            product.setGoodsSpecificationNameValue(goodsSpecification.getValue());
+                            productDao.update(product);
+                        }
                     }
                 }
             }

+ 42 - 8
kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java

@@ -6,6 +6,7 @@ import com.kmall.admin.dao.*;
 import com.kmall.admin.entity.*;
 import com.kmall.admin.entity.OrderProcessRecordEntity;
 import com.kmall.admin.service.OrderService;
+import com.kmall.api.entity.GoodsVo;
 import com.kmall.common.constant.Dict;
 import com.kmall.api.service.merch.OmsMerchPropertiesBuilder;
 import com.kmall.api.util.CommonUtil;
@@ -400,8 +401,7 @@ public class OrderServiceImpl implements OrderService {
         List<OrderGoodsEntity> orderGoodsVoList = orderGoodsDao.queryList(map);
         for (OrderGoodsEntity orderGoodsEntity : orderGoodsVoList) {
             ProductStoreRelaEntity storeRelaEntity = productStoreRelaDao
-                    .queryByStoreIdProductId(Long.valueOf(order.getStoreId()),
-                            Long.valueOf(orderGoodsEntity.getProductId()));
+                    .queryByStoreIdProductId(Long.valueOf(order.getStoreId()),Long.valueOf(orderGoodsEntity.getProductId()));
             if (null == storeRelaEntity || null == storeRelaEntity.getSellVolume()) {
                 storeRelaEntity.setSellVolume(0);
             }
@@ -409,12 +409,46 @@ public class OrderServiceImpl implements OrderService {
             if (sellVolume.compareTo(Constant.ZERO) < 0) {
                 sellVolume = Constant.ZERO;
             }
-            storeRelaEntity.setSellVolume(Integer.parseInt(sellVolume.toString()));
-            if (null == storeRelaEntity.getStockNum()) {
-                storeRelaEntity.setStockNum(0);
+
+            Integer stockNum = 0;
+            // TODO: 2019/3/5  普通商品不受共享库存影响,直接取门店配置库存
+            if(storeRelaEntity.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_00.getItem())){
+                if (storeRelaEntity.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_1.getItem())) {
+                    //还原商户商品库存
+                    stockNum = storeRelaEntity.getGoodsNumber();
+                    BigDecimal goodsSellVolume = new BigDecimal(storeRelaEntity.getGoodsSellVolume() - orderGoodsEntity.getNumber());//销售量
+                    if (goodsSellVolume.compareTo(Constant.ZERO) < 0) {
+                        goodsSellVolume = Constant.ZERO;
+                    }
+                    GoodsEntity goodsEntity = goodsDao.queryObject(storeRelaEntity.getGoodsId());
+                    if(goodsEntity!=null){
+                        goodsEntity.setGoodsNumber(stockNum + orderGoodsEntity.getNumber());
+                        goodsEntity.setSellVolume(Integer.parseInt(goodsSellVolume.toString()));
+                        goodsDao.update(goodsEntity);
+                    }
+                }
+                if (storeRelaEntity.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_0.getItem())) {
+                    //还原门店库存
+                    if (null == storeRelaEntity.getStockNum()) {
+                        stockNum = 0;
+                    }else{
+                        stockNum = storeRelaEntity.getStockNum();
+                    }
+                    storeRelaEntity.setSellVolume(Integer.parseInt(sellVolume.toString()));
+                    storeRelaEntity.setStockNum(stockNum + orderGoodsEntity.getNumber());//库存数量
+                    productStoreRelaDao.update(storeRelaEntity);
+                }
+            }else {
+                //还原门店库存
+                if (null == storeRelaEntity.getStockNum()) {
+                    stockNum = 0;
+                }else{
+                    stockNum = storeRelaEntity.getStockNum();
+                }
+                storeRelaEntity.setSellVolume(Integer.parseInt(sellVolume.toString()));
+                storeRelaEntity.setStockNum(stockNum + orderGoodsEntity.getNumber());//库存数量
+                productStoreRelaDao.update(storeRelaEntity);
             }
-            storeRelaEntity.setStockNum(storeRelaEntity.getStockNum() + orderGoodsEntity.getNumber());//库存数量
-            productStoreRelaDao.update(storeRelaEntity);
         }
     }
     /**
@@ -657,7 +691,7 @@ public class OrderServiceImpl implements OrderService {
                         productInfo.setStockNum(productInfo.getStockNum() - cartEntity.getNumber());
                         productInfo.setStoreId(Long.valueOf(storeId));
                         productInfo.addSellVolume();
-                        productStoreRelaDao.updateStockNum(productInfo);
+                        productStoreRelaDao.updateStockNum(productInfo);//修改普通商品库存
                     }
                 }
             }

+ 2 - 2
kmall-admin/src/main/java/com/kmall/admin/service/impl/ProductServiceImpl.java

@@ -31,8 +31,8 @@ public class ProductServiceImpl implements ProductService {
     }
 
     @Override
-    public ProductEntity queryObjectByGoodsId(String goodsId) {
-        return productDao.queryObjectByGoodsId(goodsId);
+    public ProductEntity queryObjectByGoodsIdAndStoreId(String goodsId,String storeId) {
+        return productDao.queryObjectByGoodsIdAndStoreId(goodsId,storeId);
     }
 
     @Override

+ 40 - 10
kmall-admin/src/main/java/com/kmall/admin/service/impl/ProductStoreRelaServiceImpl.java

@@ -88,7 +88,6 @@ public class ProductStoreRelaServiceImpl implements ProductStoreRelaService {
         ImmutableBiMap.Builder builder = new ImmutableBiMap.Builder();
         builder.put("storeId", "门店");
         builder.put("goodsId", "商品");
-        builder.put("stockNum", "库存");
         builder.put("attributeCategory", "一级分类");
         builder.put("categoryId", "二级分类");
         builder.put("brandId", "品牌");
@@ -99,6 +98,14 @@ public class ProductStoreRelaServiceImpl implements ProductStoreRelaService {
             throw new RRException(r.get("msg").toString());
         } else {
             goodsEntity = goodsDao.queryObject(productStoreRela.getGoodsId());
+            if(Dict.orderBizType.item_00.getItem().equalsIgnoreCase(goodsEntity.getGoodsBizType())){
+                if(Dict.isStockShare.item_0.getItem().equalsIgnoreCase(goodsEntity.getIsStockShare())){
+                    builder.put("stockNum", "库存");
+                }
+            }else{
+                builder.put("stockNum", "库存");
+            }
+
             if (Dict.orderBizType.item_11.getItem().equals(goodsEntity.getGoodsBizType())) {
                 // 普通商品校验商品规格
                 builder.put("specification", "规格");
@@ -125,16 +132,19 @@ public class ProductStoreRelaServiceImpl implements ProductStoreRelaService {
         if(!goodsEntity.getMerchSn().equalsIgnoreCase(productStoreRela.getMerchSn())) {
             throw new RRException("该商品所属商户不属于该门店所属商户!");
         }
+        String storeId = String.valueOf(productStoreRela.getStoreId());
+        String goodsId = String.valueOf(goodsEntity.getId());
+
         Map<String, Object> map = Maps.newHashMap();
-        map.put("goodsId", goodsEntity.getId());
-        map.put("storeId", productStoreRela.getStoreId());
+        map.put("goodsId", goodsId);
+        map.put("storeId", storeId);
         List<ProductStoreRelaEntity> storeRelaList = querySameList(map);
         if (storeRelaList != null && storeRelaList.size() > 0) {
             throw new RRException("该门店已存在此商品!");
         }
 
         SysUserEntity user = ShiroUtils.getUserEntity();
-        ProductEntity product = productDao.queryObjectByGoodsId(String.valueOf(goodsEntity.getId()));
+        ProductEntity product = productDao.queryObjectByGoodsIdAndStoreId(goodsId, "");
 
 //        GoodsEntity goods = new GoodsEntity();
 //        goods.setRetailPrice(productStoreRela.getRetailPrice());
@@ -153,10 +163,22 @@ public class ProductStoreRelaServiceImpl implements ProductStoreRelaService {
             goodsSpecification.setValue(productStoreRela.getSpecification());
             goodsSpecification.setSpecificationId(1);
             goodsSpecificationDao.save(goodsSpecification);
+
             // 修改产品
-            product.setGoodsSpecificationIds(goodsSpecification.getId().toString());
-            product.setGoodsSpecificationNameValue(goodsSpecification.getValue());
-            productDao.update(product);
+            if(product == null){
+                product = new ProductEntity();
+                product.setGoodsSn(goodsEntity.getGoodsSn());
+                product.setGoodsSpecificationNameValue(goodsSpecification.getValue());
+                product.setGoodsSpecificationIds(goodsSpecification.getId().toString());
+                product.setGoodsId(goodsEntity.getId());
+                product.setGoodsNumber(goodsEntity.getGoodsNumber());
+                product.setGoodsDefault(0);
+                productDao.save(product);
+            }else{
+                product.setGoodsSpecificationIds(goodsSpecification.getId().toString());
+                product.setGoodsSpecificationNameValue(goodsSpecification.getValue());
+                productDao.update(product);
+            }
         }/* else {
             productStoreRela.setRetailPrice(goodsEntity.getRetailPrice());
             productStoreRela.setMarketPrice(goodsEntity.getMarketPrice());
@@ -230,9 +252,12 @@ public class ProductStoreRelaServiceImpl implements ProductStoreRelaService {
             throw new RRException("该商品所属商户不属于该门店所属商户!");
         }
 
+        String storeId = String.valueOf(productStoreRela.getStoreId());
+        String goodsId = String.valueOf(goodsEntity.getId());
+
         Map<String, Object> map = Maps.newHashMap();
-        map.put("goodsId", goodsEntity.getId());
-        map.put("storeId", productStoreRela.getStoreId());
+        map.put("goodsId", goodsId);
+        map.put("storeId", storeId);
         map.put("id", productStoreRela.getId());
         List<ProductStoreRelaEntity> storeRelaList = querySameList(map);
         if (storeRelaList != null && storeRelaList.size() > 0) {
@@ -245,6 +270,11 @@ public class ProductStoreRelaServiceImpl implements ProductStoreRelaService {
 //        goods.setMarketPrice(productStoreRela.getMarketPrice());
 //        goods.setId(goodsEntity.getId());
 //        goodsDao.update(goods);
+        ProductEntity product = productDao.queryObjectByGoodsIdAndStoreId(goodsId, storeId);
+        if(product == null){
+            throw new RRException("该商品规格信息为空!请完善商品数据");
+        }
+        productStoreRela.setProductId(product.getId());
         if (Dict.orderBizType.item_11.getItem().equals(goodsEntity.getGoodsBizType())) {
             // 添加商品规格
             GoodsSpecificationEntity goodsSpecification = goodsSpecificationDao.queryByGoodsId(goodsEntity.getId());
@@ -252,11 +282,11 @@ public class ProductStoreRelaServiceImpl implements ProductStoreRelaService {
             goodsSpecificationDao.update(goodsSpecification);
 
             // 修改产品
-            ProductEntity product = productDao.queryObjectByGoodsId(String.valueOf(goodsEntity.getId()));
             product.setGoodsSpecificationIds(goodsSpecification.getId().toString());
             product.setGoodsSpecificationNameValue(goodsSpecification.getValue());
             productDao.update(product);
         }
+
         // 修改商品参数
         List<GoodsAttributeEntity> attributeEntityList = productStoreRela.getAttributeEntityList();
         if (attributeEntityList != null && attributeEntityList.size() > 0) {

+ 4 - 1
kmall-admin/src/main/java/com/kmall/admin/service/impl/ThirdMerchantBizServiceImpl.java

@@ -27,7 +27,10 @@ public class ThirdMerchantBizServiceImpl implements ThirdMerchantBizService {
     public ThirdMerchantBizEntity queryObject(Integer thirdMerchSn) {
         return thirdMerchantBizDao.queryObject(thirdMerchSn);
     }
-
+    @Override
+    public ThirdMerchantBizEntity getThirdMerchangByCode(String thirdMerchCode){
+        return thirdMerchantBizDao.getThirdMerchangByCode(thirdMerchCode);
+    }
     @Override
     public List<ThirdMerchantBizEntity> queryList(Map<String, Object> map) {
         return thirdMerchantBizDao.queryList(map);

+ 19 - 0
kmall-admin/src/main/java/com/kmall/admin/utils/XBasicDataSource.java

@@ -0,0 +1,19 @@
+//package com.kmall.admin.utils;
+//
+//import java.sql.DriverManager;
+//import java.sql.SQLException;
+//import org.apache.commons.dbcp.BasicDataSource;
+//
+///**
+// * @author huangyq
+// * @version 1.0
+// * 2019-02-28 16:48
+// */
+//public class XBasicDataSource extends BasicDataSource{
+//    @Override
+//    public synchronized void close() throws SQLException{
+////  System.out.println("......输出数据源Driver的url:"+DriverManager.getDriver(url));
+//        DriverManager.deregisterDriver(DriverManager.getDriver(url));
+//        super.close();
+//    }
+//}

+ 5 - 2
kmall-admin/src/main/resources/mybatis/mapper/GoodsDao.xml

@@ -63,15 +63,17 @@
         <result column="storeMarketPrice" property="storeMarketPrice" />
         <result column="storeRetailPrice" property="storeRetailPrice" />
         <result column="third_party_merch_code" property="thirdPartyMerchCode" />
+        <result column="isStockShare" property="isStockShare" />
     </resultMap>
 
     <select id="queryObject" resultType="com.kmall.admin.entity.GoodsEntity">
         SELECT
             a.*, CASE
-        when g.id > 0 then 2 else 0 end as goodsType
+        when g.id > 0 then 2 else 0 end as goodsType,mb.is_stock_share isStockShare,mb.third_party_merch_code thirdPartyMerchCode
         FROM
             mall_goods a
         LEFT JOIN mall_goods_group g ON g.goods_id = a.id
+        left join third_merchant_biz mb on a.third_party_merch_code = mb.third_party_merch_code and mb.merch_sn=a.merch_sn
         AND g.open_status != 3
         WHERE a.id = #{value}
     </select>
@@ -115,10 +117,11 @@
         select
         mall_goods.*,
         case when mall_goods_group.id > 0 then 2 else 0 end as goodsType,
-        m.merch_name merchName
+        m.merch_name merchName, mb.is_stock_share isStockShare
         from mall_goods
         left join mall_merch m on mall_goods.merch_sn = m.merch_sn
         left join mall_goods_group on mall_goods_group.goods_id = mall_goods.id and mall_goods_group.open_status != 3
+        left join third_merchant_biz mb on mb.third_party_merch_code = mall_goods.third_party_merch_code and mb.merch_sn=mall_goods.merch_sn
         WHERE 1=1
         <!--  数据过滤  -->
         ${filterSql}

+ 16 - 4
kmall-admin/src/main/resources/mybatis/mapper/ProductDao.xml

@@ -26,11 +26,23 @@
 		where id = #{id}
 	</select>
 
-    <select id="queryObjectByGoodsId" resultType="com.kmall.admin.entity.ProductEntity">
+    <select id="queryObjectByGoodsIdAndStoreId" resultType="com.kmall.admin.entity.ProductEntity">
         select
-        *
-        from mall_product
-        where goods_id = #{goodsId}
+            p.id,
+			p.goods_id,
+			p.goods_specification_ids,
+			p.goods_specification_name_value,
+			p.goods_sn,
+			p.goods_number,
+			p.goods_default
+        from mall_product p
+        <if test="storeId != null and storeId != ''">
+          left join mall_product_store_rela r on p.id = r.product_id and p.goods_id = r.goods_id
+        </if>
+        where p.goods_id = #{goodsId}
+        <if test="storeId != null and storeId != ''">
+            and r.store_id = #{storeId}
+        </if>
     </select>
 
     <select id="queryList" resultType="com.kmall.admin.entity.ProductEntity">

+ 15 - 3
kmall-admin/src/main/resources/mybatis/mapper/ProductStoreRelaDao.xml

@@ -36,7 +36,10 @@
         <result column="attribute_category" property="attributeCategory" />
         <result column="brand_id" property="brandId" />
         <result column="freight_id" property="freightId" />
-
+        <result column="goodsNumber" property="goodsNumber" />
+        <result column="thirdPartyMerchCode" property="thirdPartyMerchCode" />
+        <result column="isStockShare" property="isStockShare" />
+        <result column="goodsSellVolume" property="goodsSellVolume" />
     </resultMap>
 
     <select id="queryObject" resultType="com.kmall.admin.entity.ProductStoreRelaEntity">
@@ -99,9 +102,13 @@
             a.category_id,
             a.attribute_category,
             a.brand_id,
-            a.freight_id
+            a.freight_id,
+            b.goods_number goodsNumber,
+            mb.is_stock_share isStockShare,
+            b.sell_volume goodsSellVolume
         from mall_product_store_rela a
         left join mall_goods b on a.goods_id = b.id
+        left join third_merchant_biz mb on b.third_party_merch_code = mb.third_party_merch_code and mb.merch_sn=b.merch_sn
         left join mall_product c on a.product_id = c.id
         LEFT JOIN mall_category cg ON a.category_id = cg.id
         left join mall_store s on a.store_id = s.id
@@ -153,9 +160,13 @@
         a.category_id,
         a.attribute_category,
         a.brand_id,
-        a.freight_id
+        a.freight_id,
+        b.goods_number goodsNumber,
+        b.third_party_merch_code thirdPartyMerchCode,
+        mb.is_stock_share isStockShare
         from mall_product_store_rela a
         left join mall_goods b on a.goods_id = b.id
+        left join third_merchant_biz mb on mb.third_party_merch_code = b.third_party_merch_code and mb.merch_sn=b.merch_sn
         left join mall_merch m on a.merch_sn = m.merch_sn
         left join mall_product c on a.product_id = c.id
         LEFT JOIN mall_category cg ON a.category_id = cg.id
@@ -282,6 +293,7 @@
         select count(a.id)
         from mall_product_store_rela a
         left join mall_goods b on a.goods_id = b.id
+        left join third_merchant_biz mb on mb.third_party_merch_code = b.third_party_merch_code and mb.merch_sn=b.merch_sn
         left join mall_product c on a.product_id = c.id
         LEFT JOIN mall_category cg ON a.category_id = cg.id
         left join mall_store s on a.store_id = s.id

+ 18 - 2
kmall-admin/src/main/resources/mybatis/mapper/ThirdMerchantBizDao.xml

@@ -8,6 +8,8 @@
 		<result property="merchSn" column="merch_sn"/>
         <result property="thirdPartyMerchCode" column="third_party_merch_code"/>
         <result property="thirdPartyMerchName" column="third_party_merch_name"/>
+		<result property="isStockShare" column="is_stock_share"/>
+		<result property="isStoreUserShare" column="is_store_user_share"/>
         <result property="isValid" column="is_valid"/>
         <result property="createrSn" column="creater_sn"/>
         <result property="createTime" column="create_time"/>
@@ -23,6 +25,8 @@
 			`third_party_merch_code`,
 			`third_party_merch_name`,
 			`is_valid`,
+			is_stock_share,
+			is_store_user_share,
 			`creater_sn`,
 			`create_time`,
 			`moder_sn`,
@@ -39,6 +43,8 @@
 		`third_party_merch_code`,
 		`third_party_merch_name`,
 		`is_valid`,
+		is_stock_share,
+		is_store_user_share,
 		`creater_sn`,
 		`create_time`,
 		`moder_sn`,
@@ -55,6 +61,8 @@
 		`third_party_merch_code`,
 		`third_party_merch_name`,
 		`is_valid`,
+		is_stock_share,
+		is_store_user_share,
 		`creater_sn`,
 		`create_time`,
 		`moder_sn`,
@@ -71,6 +79,8 @@
     		`third_party_merch_code`,
     		`third_party_merch_name`,
     		`is_valid`,
+			is_stock_share,
+		is_store_user_share,
     		`creater_sn`,
     		`create_time`,
     		`moder_sn`,
@@ -113,13 +123,15 @@
 			and third_party_merch_code = #{thirdPartyMerchCode}
 		</if>
 	</select>
-	 
+
 	<insert id="save" parameterType="com.kmall.admin.entity.ThirdMerchantBizEntity" useGeneratedKeys="true" keyProperty="thirdMerchSn">
 		insert into third_merchant_biz(
 			`merch_sn`,
 			`third_party_merch_code`,
 			`third_party_merch_name`,
 			`is_valid`,
+			is_stock_share,
+			is_store_user_share,
 			`creater_sn`,
 			`create_time`,
 			`moder_sn`,
@@ -130,13 +142,15 @@
 			#{thirdPartyMerchCode},
 			#{thirdPartyMerchName},
 			#{isValid},
+			#{isStockShare},
+			#{isStoreUserShare},
 			#{createrSn},
 			#{createTime},
 			#{moderSn},
 			#{modTime},
 			#{tstm})
 	</insert>
-	 
+
 	<update id="update" parameterType="com.kmall.admin.entity.ThirdMerchantBizEntity">
 		update third_merchant_biz 
 		<set>
@@ -144,6 +158,8 @@
 			<if test="thirdPartyMerchCode != null">`third_party_merch_code` = #{thirdPartyMerchCode}, </if>
 			<if test="thirdPartyMerchName != null">`third_party_merch_name` = #{thirdPartyMerchName}, </if>
 			<if test="isValid != null">`is_valid` = #{isValid}, </if>
+			<if test="isStockShare != null">`is_stock_share` = #{isStockShare}, </if>
+			<if test="isStoreUserShare != null">`is_store_user_share` = #{isStoreUserShare}, </if>
 			<if test="createrSn != null">`creater_sn` = #{createrSn}, </if>
 			<if test="createTime != null">`create_time` = #{createTime}, </if>
 			<if test="moderSn != null">`moder_sn` = #{moderSn}, </if>

+ 8 - 0
kmall-admin/src/main/resources/spring/spring-jdbc.xml

@@ -50,6 +50,14 @@
                 <ref bean="wall-filter"/>
             </list>
         </property>
+        <!--&lt;!&ndash; 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 &ndash;&gt;-->
+        <property name="timeBetweenEvictionRunsMillis" value="60000" />
+        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
+        <property name="minEvictableIdleTimeMillis" value="300000" />
+        <!-- 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效 -->
+        <property name="testWhileIdle" value="true" />
+        <!-- 指定每个连接上PSCache的大小   -->
+        <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
     </bean>
 
     <!-- 慢sql日志 -->

+ 13 - 8
kmall-admin/src/main/webapp/WEB-INF/page/shop/goods.html

@@ -107,10 +107,12 @@
                 #if($shiro.hasPermission("goods:delete"))
                 <i-button type="error" @click="del"><i class="fa fa-trash-o"></i>&nbsp;删除</i-button>
                 #end
+
                 #if($shiro.hasPermission("goods:unSaleBatch"))
                 <i-button type="primary" @click="enSale"><i class="fa fa-hand-o-up"></i>&nbsp;上架</i-button>
                 <i-button type="dashed" @click="unSale"><i class="fa fa-hand-o-down"></i>&nbsp;下架</i-button>
                 #end
+
                 <!--<i-button type="info" @click="goodsExport"><i class="fa fa-plus"></i>&nbsp;商品导入</i-button>-->
                 <!--<i-button type="info" @click="sameGoodsExport"><i class="fa fa-plus"></i>&nbsp;普货商品导入</i-button>-->
 
@@ -160,10 +162,17 @@
                         </i-select>
                     </Form-item>
                 <Form-item label="第三方商户" prop="merchSn">
-                    <i-select v-model="goods.thirdPartyMerchCode" placeholder="第三方商户" label-in-value>
+                    <i-select v-model="goods.thirdPartyMerchCode" placeholder="第三方商户" @on-change="showStockShare" label-in-value>
                         <i-option v-for="thirdMerchant in thirdMerchantBizList" :value="thirdMerchant.thirdPartyMerchCode" :key="thirdMerchant.thirdPartyMerchCode">{{thirdMerchant.thirdPartyMerchName}}</i-option>
                     </i-select>
                 </Form-item>
+                <Form-item label="货品业务类型" prop="goodsBizType" >
+                    <i-select v-model="goods.goodsBizType"  placeholder="货品业务类型"
+                              label-in-value style="width: 268px;" @on-change="changeGoodsBizType">
+                        <i-option v-for="macro in macros" :value="macro.value" :key="macro.id">{{macro.name}}
+                        </i-option>
+                    </i-select>
+                </Form-item>
                     <Form-item label="商品编码" prop="goodsSn">
                         <i-input v-model="goods.goodsSn" placeholder="商品编码"/>
                     </Form-item>
@@ -185,13 +194,6 @@
                     <Form-item label="产品条码" prop="prodBarcode">
                         <i-input v-model="goods.prodBarcode" placeholder="产品条码"/>
                     </Form-item>
-                    <Form-item label="货品业务类型" prop="goodsBizType" >
-                        <i-select v-model="goods.goodsBizType" filterable placeholder="货品业务类型"
-                                  label-in-value style="width: 268px;" @on-change="changeGoodsBizType">
-                            <i-option v-for="macro in macros" :value="macro.value" :key="macro.id">{{macro.name}}
-                            </i-option>
-                        </i-select>
-                    </Form-item>
                 <Form-item label="供应商" prop="supplierId">
                     <i-select v-model="goods.supplierId" placeholder="供应商"
                               label-in-value style="width: 268px;">
@@ -212,6 +214,9 @@
                     <!--<Form-item label="零售价" prop="retailPrice">-->
                         <!--<Input-number :min="0.01" :step="0.01" v-model="goods.retailPrice" placeholder="零售价" style="width: 268px;"/>-->
                     <!--</Form-item>-->
+                    <Form-item label="商品库存" prop="goodsNumber" v-show="isStockShare">
+                        <i-input v-model="goods.goodsNumber" placeholder="商品库存" style="width: 268px;"/>
+                    </Form-item>
                     <Form-item label="商品税率(0.00)" prop="goodsRate">
                         <Input-number :min="0.001" :step="0.001" v-model="goods.goodsRate" placeholder="商品税率" style="width: 268px;"/>
                     </Form-item>

+ 19 - 5
kmall-admin/src/main/webapp/WEB-INF/page/shop/storeProductStock.html

@@ -121,20 +121,34 @@
         <i-form ref="formValidate" :model="productStoreRela" :rules="ruleValidate" :label-width="80">
             <Form-item label="门店" prop="storeId">
                 <i-select v-model="productStoreRela.storeId" placeholder="门店" filterable @on-change="getGoods"
-                          label-in-value>
+                          label-in-value v-show="isOperatorShow" disabled>
+                    <i-option v-for="store in stores" :value="store.id"
+                              :key="store.id">{{store.storeName}}
+                    </i-option>
+                </i-select>
+                <i-select v-model="productStoreRela.storeId" placeholder="门店" filterable @on-change="getGoods"
+                          label-in-value v-show="!isOperatorShow">
                     <i-option v-for="store in stores" :value="store.id"
                               :key="store.id">{{store.storeName}}
                     </i-option>
                 </i-select>
             </Form-item>
             <Form-item label="商品" prop="goodsId">
-                <i-select v-model="productStoreRela.goodsId" filterable @on-change="changeGoods" label-in-value>
+                <i-select v-model="productStoreRela.goodsId" filterable @on-change="changeGoods" label-in-value  v-show="isOperatorShow" disabled>
+                    <i-option v-for="goods in goodss" :value="goods.id" :key="goods.id">{{goods.name}}</i-option>
+                </i-select>
+                <i-select v-model="productStoreRela.goodsId" filterable @on-change="changeGoods" label-in-value  v-show="!isOperatorShow">
                     <i-option v-for="goods in goodss" :value="goods.id" :key="goods.id">{{goods.name}}</i-option>
                 </i-select>
             </Form-item>
-            <Form-item label="库存" prop="stockNum">
+            <div v-show="isStockShare"><span style="margin-left: 80px;color: red;font-size: 12px;">* 请先维护第三方商户门店商户是否共享字段,如字段为是则去修改商品库存,设置为否则可修改门店库存</span></div>
+            <Form-item label="库存" prop="stockNum" v-show="isStockShare"><!--共享-->
                 <Input-number :min="0" :step="1" v-model="productStoreRela.stockNum" placeholder="总库存"
-                              style="width: 268px;"/>
+                              style="width: 268px;" disabled/>
+            </Form-item>
+            <Form-item label="库存" prop="stockNum" v-show="!isStockShare"><!--不共享-->
+                <Input-number :min="0" :step="1" v-model="productStoreRela.stockNum" placeholder="总库存"
+                              style="width: 268px;" />
             </Form-item>
             <Form-item v-if="showInput" label="商品类型" prop="categoryId" style="height: 30px;">
                 <!--<i-input v-model="goods.categoryName" @on-click="categoryTree" icon="eye" readonly="readonly" placeholder="商品类型"/>-->
@@ -166,7 +180,7 @@
                 </i-select>
             </Form-item>
             <Form-item v-if="showInputSpecification" label="规格" prop="specification">
-                <i-input v-model="specification" placeholder="规格" style="width: 268px;"/>
+                <i-input v-model="productStoreRela.specification" placeholder="规格" style="width: 268px;"/>
             </Form-item>
             <Form-item  v-if="showInput" label="零售价" prop="retailPrice">
                 <Input-number :min="0.01" :step="0.01" v-model="productStoreRela.retailPrice" placeholder="零售价格"

+ 20 - 0
kmall-admin/src/main/webapp/WEB-INF/page/shop/thirdmerchantbiz.html

@@ -45,6 +45,26 @@
             <Form-item label="第三方商户名称" prop="thirdPartyMerchName">
                 <i-input v-model="thirdMerchantBiz.thirdPartyMerchName" placeholder="第三方商户名称"/>
             </Form-item>
+            <Form-item label="库存是否共享" prop="isStockShare" v-show="isOperate">
+                <Radio-group v-model="thirdMerchantBiz.isStockShare">
+                    <Radio label="1">
+                        <span>是</span>
+                    </Radio>
+                    <Radio label="0">
+                        <span>否</span>
+                    </Radio>
+                </Radio-group>
+            </Form-item>
+            <Form-item label="门店用户是否共享" prop="isStoreUserShare" v-show="isOperate">
+                <Radio-group v-model="thirdMerchantBiz.isStoreUserShare">
+                    <Radio label="1">
+                        <span>是</span>
+                    </Radio>
+                    <Radio label="0">
+                        <span>否</span>
+                    </Radio>
+                </Radio-group>
+            </Form-item>
             <Form-item label="是否有效" prop="isValid">
                 <Radio-group v-model="thirdMerchantBiz.isValid">
                     <Radio label="1">

+ 1 - 6
kmall-admin/src/main/webapp/WEB-INF/web.xml

@@ -1,3 +1,4 @@
+
 <?xml version="1.0" encoding="UTF-8"?>
 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -24,12 +25,6 @@
         </param-value>
     </context-param>
 
-    <!--<context-param>
-        <param-name>log4jRefreshInterval</param-name>
-        <param-value>600000</param-value>
-
-    </context-param>-->
-
     <!--logback 日志-->
     <context-param>
         <param-name>logbackConfigLocation</param-name>

+ 47 - 1
kmall-admin/src/main/webapp/js/shop/goods.js

@@ -24,6 +24,16 @@ $(function () {
                     return '普通货物';
                 }
             },
+            {label: '库存是否共享', name: 'isStockShare', index: 'isStockShare', width: 80, align: 'center',
+                formatter: function (value) {
+                    if (value == '0') {
+                        return '否';
+                    } else if (value == '1') {
+                        return '是';
+                    }
+                    return '-';
+                }},
+            {label: '商品库存', name: 'goodsNumber', index: 'goodsNumber', width: 80, align: 'center'},
             // {label: '零售价格', name: 'retailPrice', index: 'retail_price', width: 80, align: 'center'},
             // {label: '市场价', name: 'marketPrice', index: 'market_price', width: 80, align: 'center'},
             {
@@ -145,7 +155,11 @@ var vm = new Vue({
         cusNationCodeList: [],
         merchList: [],
         suppliers: [],
-        thirdMerchantBizList: []
+        thirdMerchantBizList: [],
+        isStockShare: false,
+        goodsBizType: '',
+        isOperator: '',
+        share: ''
     },
     methods: {
         delSpeRow: function (index) {
@@ -190,6 +204,7 @@ var vm = new Vue({
         },
         add: function () {
             vm.showList = false;
+            vm.isOperator='add';
             vm.title = "新增";
             vm.uploadList = [];
             vm.goods = {primaryPicUrl: '', listPicUrl: '',videoUrl:'',  categoryId: '', isOnSale: 1, isAppExclusive: 0, isLimited: 0, isHot: 0, categoryName: '', retailPrice: '', marketPrice: '', goodsRate: '', sortOrder: '' };
@@ -212,6 +227,7 @@ var vm = new Vue({
             if (id == null) {
                 return;
             }
+            vm.isOperator='update';
             vm.showList = false;
             vm.title = "修改";
             vm.uploadList = [];
@@ -220,6 +236,13 @@ var vm = new Vue({
             opt.value = vm.goods.categoryId;
             opt.flag = 1;
             vm.getAttributes(opt);*/
+            // var opt = {};
+            // opt.value = vm.goods.thirdPartyMerchCode;
+            // vm.showStockShare(opt);
+            // var opt2 = {};
+            // opt2.value = vm.goods.goodsBizType;
+            // vm.changeGoodsBizType(opt2);
+
             vm.thirdMerchantBizList = [];
             vm.getMacro();
             vm.getCusUnitCodeList();
@@ -395,6 +418,8 @@ var vm = new Vue({
         getInfo: function (id) {
             $.get("../goods/info/" + id, function (r) {
                 vm.goods = r.goods;
+                vm.goodsBizType = r.goods.goodsBizType;
+
                 /*vm.categoryId = r.goods.categoryId;
                 // vm.getCategory();
                 var opt = {};
@@ -467,6 +492,18 @@ var vm = new Vue({
                 }
             });
         },
+        showStockShare:function(opt){
+            var thirdMerchantCode = opt.value;
+            $.get("../thirdmerchantbiz/infoByCode?thirdMerchantCode=" + thirdMerchantCode, function (r) {
+                vm.share = r.thirdMerchantBiz.isStockShare;
+                if(vm.goods.goodsBizType == '00' && r.thirdMerchantBiz.isStockShare == 1){
+                    vm.isStockShare = true;
+                }else{
+                    vm.isStockShare = false;
+                    vm.goods.goodsNumber= '';
+                }
+            });
+        },
         changeGoodsBizType: function(opt) {
             var goodsBizType = opt.value;
             if (vm.goods.goodsBizType == '10' || vm.goods.goodsBizType == '02') {
@@ -474,6 +511,15 @@ var vm = new Vue({
             } else {
                 vm.showInput = true;
             }
+            // console.log(vm.goods.goodsBizType)
+            // console.log(vm.share)
+            if(vm.goods.goodsBizType == '00' && vm.share == 1){
+                vm.isStockShare = true;
+            }else{
+                vm.isStockShare = false;
+                vm.goods.goodsNumber= '';
+            }
+
         },
         handleView(name) {
             this.imgName = name;

+ 37 - 29
kmall-admin/src/main/webapp/js/shop/storeProductStock.js

@@ -24,9 +24,18 @@ $(function () {
             {label: '商品编码', name: 'goodsSn', index: 'goodsSn', width: 80, align: 'center'},
             {label: '名称', name: 'goodsName', index: 'goodsName', width: 160, align: 'left'},
             {label: '产品编码', name: 'productSn', index: 'productSn', width: 80, align: 'center'},
-            {label: '库存', name: 'stockNum', index: 'stockNum', width: 80, align: 'center'},
+            {label: '库存是否共享', name: 'isStockShare', index: 'isStockShare', width: 80, align: 'center',
+                formatter: function (value) {
+                    if (value == '0') {
+                        return '否';
+                    } else if (value == '1') {
+                        return '是';
+                    }
+                    return '-';
+                }},
+            {label: '门店库存', name: 'stockNum', index: 'stockNum', width: 80, align: 'center'},
             {label: '零售价格', name: 'retailPrice', index: 'retailPrice', width: 80, align: 'center'},
-            {label: '市场价', name: 'marketPrice', index: 'marketPrice', width: 80, align: 'center'},
+            // {label: '市场价', name: 'marketPrice', index: 'marketPrice', width: 80, align: 'center'},
             // {label: '库存价格', name: 'stockPrice', index: 'stockPrice', width: 80},
             {
                 label: '销售量',
@@ -143,7 +152,9 @@ var vm = new Vue({
         freights: [],
         storeId: 0,
         specification: '',
-        isOperator: ''
+        isOperator: '',
+        isStockShare: false,
+        isOperatorShow: false
     },
     methods: {
         changeGoods: function (opt) {
@@ -157,30 +168,26 @@ var vm = new Vue({
                     } else {
                         vm.showInputSpecification = false;
                     }
+
+                    $.get("../thirdmerchantbiz/infoByCode?thirdMerchantCode=" + r.goods.thirdPartyMerchCode, function (rr) {
+                        if(rr.thirdMerchantBiz==null){
+                            alert('请先维护第三方商户,门店商户是否共享字段');
+                            vm.isStockShare = true;
+                            return;
+                        }
+                        if(rr.thirdMerchantBiz.isStockShare==null){
+                            alert('请先维护商品信息,第三方商户代码字段');
+                            vm.isStockShare = true;
+                            return;
+                        }
+
+                        if(r.goods.goodsBizType == '00' && rr.thirdMerchantBiz.isStockShare == 1){//共享
+                            vm.isStockShare = true;
+                        }else{
+                            vm.isStockShare = false;
+                        }
+                    });
                 });
-                // $.get("../productstorerela/infoByGoodsId?goodsId=" + goodsId + "&storeId=" + vm.storeId, function (r) {
-                //     vm.productStoreRela = r.productStoreRela;
-                //     vm.showInput = true;
-                //     if (r.productStoreRela.goodsBizType == 11) {
-                //         vm.showInputSpecification = true;
-                //     }else{
-                //         vm.showInputSpecification = false;
-                //     }
-                //
-                //     vm.categoryId = r.productStoreRela.categoryId;
-                //     var opt = {};
-                //     opt.value = vm.productStoreRela.attributeCategory;
-                //     vm.changeCategories(opt);
-                //     // if (r.productStoreRela.attributeEntityList.length > 0) {
-                //     //     vm.attributeEntityList = r.productStoreRela.attributeEntityList;
-                //     // } else {
-                //     //     vm.attributeEntityList = [{'id': '', 'goodsId': '', 'attributeId': '', 'value': '', 'isDelete': 0}];
-                //     // }
-                //     // console.log(r.goods.retailPrice);
-                //     // console.log(r.goods.marketPrice);
-                //     // vm.productStoreRela.retailPrice = r.goods.retailPrice;
-                //     // vm.productStoreRela.marketPrice = r.goods.marketPrice;
-                // });
             }
         },
         changeQueryCategories: function (opt) {
@@ -205,6 +212,7 @@ var vm = new Vue({
             vm.showList = false;
             vm.title = "新增";
             vm.isOperator = 'add';
+            vm.isOperatorShow = false;
             vm.uploadList = [];
             vm.freights = [];
             vm.brands = [];
@@ -222,6 +230,7 @@ var vm = new Vue({
             vm.showList = false;
             vm.title = "修改";
             vm.isOperator = 'update';
+            vm.isOperatorShow = true;
             vm.uploadList = [];
             vm.getInfo(id);
             var opt = {};
@@ -247,8 +256,9 @@ var vm = new Vue({
         },
         saveOrUpdate: function (event) {
             var url = vm.productStoreRela.id == null ? "../productstorerela/save" : "../productstorerela/update";
-            console.log(vm.attributeEntityList);
             vm.productStoreRela.attributeEntityList = vm.attributeEntityList;
+            console.log(vm.productStoreRela);
+            console.log(vm.productStoreRela.specification);
             $.ajax({
                 type: "POST",
                 url: url,
@@ -313,8 +323,6 @@ var vm = new Vue({
                     merchSn = vm.stores[i].merchSn;
             }
             vm.storeId = storeId;
-
-            console.log(vm.isOperator);
             if(vm.isOperator == 'add'){
                 $.get("../goods/queryAll?merchSn=" + merchSn + "&storeId=" +storeId, function (r) {
                     vm.goodss = r.list;

+ 40 - 16
kmall-admin/src/main/webapp/js/shop/thirdmerchantbiz.js

@@ -7,6 +7,25 @@ $(function () {
             {label: '商户编号', name: 'merchSn', index: 'merch_sn', width: 80, align: 'center'},
 			{label: '第三方商户代码', name: 'thirdPartyMerchCode', index: 'third_party_merch_code', width: 80, align: 'center'},
 			{label: '第三方商户名称', name: 'thirdPartyMerchName', index: 'third_party_merch_name', width: 80, align: 'center'},
+            {label: '库存是否共享', name: 'isStockShare', index: 'isStockShare', width: 80, align: 'center',
+                formatter: function (value) {
+                    if (value == '0') {
+                        return '否';
+                    } else if (value == '1') {
+                        return '是';
+                    }
+                    return '';
+                }},
+            {label: '门店用户是否共享', name: 'isStoreUserShare', index: 'isStoreUserShare', width: 80, align: 'center',
+                formatter: function (value) {
+                    if (value == '0') {
+                        return '否';
+                    } else if (value == '1') {
+                        return '是';
+                    }
+                    return '';
+                }},
+
 			{label: '是否有效', name: 'isValid', index: 'is_valid', width: 80, align: 'center',
                 formatter: function (value) {
                     if (value == '0') {
@@ -55,7 +74,7 @@ let vm = new Vue({
 	data: {
         showList: true,
         title: null,
-		thirdMerchantBiz: {isValid: ''},
+		thirdMerchantBiz: {isValid: '', isStockShare:'',isStoreUserShare:''},
 		ruleValidate: {
 			name: [
 				{required: true, message: '名称不能为空', trigger: 'blur'}
@@ -65,6 +84,7 @@ let vm = new Vue({
 		    name: ''
 		},
         merchList: [],
+        isOperate: false
 	},
 	methods: {
 		query: function () {
@@ -74,7 +94,8 @@ let vm = new Vue({
 			vm.showList = false;
 			vm.title = "新增";
             vm.getMerchList();
-			vm.thirdMerchantBiz = {isValid: 0};
+			vm.thirdMerchantBiz = {isValid: 0,isStockShare:0,isStoreUserShare:0};
+			vm.isOperate = true;
 		},
 		update: function (event) {
             let thirdMerchSn = getSelectedRow();
@@ -83,27 +104,30 @@ let vm = new Vue({
 			}
 			vm.showList = false;
             vm.title = "修改";
+            vm.isOperate = false;
             vm.getMerchList();
 
             vm.getInfo(thirdMerchSn)
 		},
 		saveOrUpdate: function (event) {
             let url = vm.thirdMerchantBiz.thirdMerchSn == null ? "../thirdmerchantbiz/save" : "../thirdmerchantbiz/update";
-			$.ajax({
-				type: "POST",
-			    url: url,
-			    contentType: "application/json",
-			    data: JSON.stringify(vm.thirdMerchantBiz),
-                success: function (r) {
-                    if (r.code === 0) {
-                        alert('操作成功', function (index) {
-                            vm.reload();
-                        });
-                    } else {
-                        alert(r.msg);
+            confirm('库存是否共享添加成功后则不可修改!确定添加?', function () {
+                $.ajax({
+                    type: "POST",
+                    url: url,
+                    contentType: "application/json",
+                    data: JSON.stringify(vm.thirdMerchantBiz),
+                    success: function (r) {
+                        if (r.code === 0) {
+                            alert('操作成功', function (index) {
+                                vm.reload();
+                            });
+                        } else {
+                            alert(r.msg);
+                        }
                     }
-                }
-			});
+                });
+            })
 		},
 		del: function (event) {
             let thirdMerchSns = getSelectedRows();

+ 111 - 15
kmall-api/src/main/java/com/kmall/api/api/ApiCartController.java

@@ -49,19 +49,24 @@ public class ApiCartController extends ApiBaseAction {
 
     @Autowired
     private ApiFreightService apiFreightService;
+    @Autowired
+    private ApiThirdMerchantBizService apiThirdMerchantBizService;
+    @Autowired
+    private ApiStoreService apiStoreService;
 
     /**
      * 获取购物车中的数据
      */
     @GetMapping("getCartMoney")
     public Object getCartMoney(@LoginUser UserVo loginUser, String checkCart) {
+        Long storeId = getStoreId();
         Map<String, Object> resultObj = Maps.newHashMap();
         //查询列表数据
         Map param = Maps.newHashMap();
         param.put("user_id", loginUser.getId());
-        Long storeId = getStoreId();
         param.put("store_id", storeId);
         param.put("checkCart",checkCart);
+        param.putAll(setIsStockShare(storeId));
         List<CartVo> cartList = cartService.queryList(param);
         //获取购物车统计信息
         Integer goodsCount = 0;
@@ -89,6 +94,19 @@ public class ApiCartController extends ApiBaseAction {
         return resultObj;
     }
 
+    private Map setIsStockShare(Long storeId){
+        Map param = Maps.newHashMap();
+        StoreVo storeVo = apiStoreService.queryObject(storeId);
+        if(storeVo != null) {
+            ThirdMerchantBizVo thirdMerchantBiz = apiThirdMerchantBizService.getThirdMerchangByCode(storeVo.getThirdPartyMerchCode());
+            if (null == thirdMerchantBiz) {
+                return toResponsFail("第三方商户为空");
+            }
+            param.put("isStockShare", thirdMerchantBiz.getIsStockShare());
+        }
+        return param;
+    }
+
     /**
      * 获取购物车中的数据
      */
@@ -104,6 +122,7 @@ public class ApiCartController extends ApiBaseAction {
         param.put("store_id", storeId);
         param.put("merchSn", getMerchSn());
         param.put("checkCart", checkCart);
+        param.putAll(setIsStockShare(storeId));
         List<CartVo> cartList = cartService.queryList(param);
         List<CartVo> validCartList = cartService.queryValidCartList(param);
         //获取购物车统计信息
@@ -196,6 +215,7 @@ public class ApiCartController extends ApiBaseAction {
         param.put("user_id", loginUser.getId());
         Long storeId = getStoreId();
         param.put("store_id", storeId);
+        param.putAll(setIsStockShare(storeId));
         List<CartVo> cartList = cartService.queryList(param);
         //获取购物车统计信息
         Integer goodsCount = 0;
@@ -256,7 +276,26 @@ public class ApiCartController extends ApiBaseAction {
         if (null == productInfo) {
             return toResponsFail("商品已下架");
         }
-        if(productInfo.getStock_num() == null || number > productInfo.getStock_num() || productInfo.getStock_num() <= 0){
+        Integer stockNum = 0;
+        ThirdMerchantBizVo thirdMerchantBizVo = apiThirdMerchantBizService.getThirdMerchangByCode(goodsInfo.getThirdPartyMerchCode());
+        if(null == thirdMerchantBizVo){
+            return toResponsFail("商品已下架");
+        }
+        //// TODO: 2019/3/5  普通商品不受共享库存影响,直接取门店配置库存
+        if(goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_11.getItem())
+                || goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_02.getItem())
+                || goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_10.getItem())){
+            stockNum = productInfo.getStock_num();
+        }
+        if(goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_00.getItem())){
+            if (thirdMerchantBizVo.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_1.getItem())){
+                stockNum = goodsInfo.getGoods_number();
+            }
+            if (thirdMerchantBizVo.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_0.getItem())){
+                stockNum = productInfo.getStock_num();
+            }
+        }
+        if(stockNum == null || number > stockNum || stockNum <= 0){
             return toResponsFail("该商品库存不足");
         }
         if (null == productInfo.getRetail_price()) {
@@ -269,6 +308,7 @@ public class ApiCartController extends ApiBaseAction {
         cartParam.put("product_id", productId);
         cartParam.put("user_id", loginUser.getId());
         cartParam.put("store_id", storeId);
+        cartParam.put("isStockShare", thirdMerchantBizVo.getIsStockShare());
         List<CartVo> cartInfoList = cartService.queryList(cartParam);
         CartVo cartInfo = null != cartInfoList && cartInfoList.size() > 0 ? cartInfoList.get(0) : null;
         if (null == cartInfo) {//添加规格名和值
@@ -288,17 +328,17 @@ public class ApiCartController extends ApiBaseAction {
             cartInfo.setGoods_specification_ids(productInfo.getGoods_specification_ids());
             cartInfo.setChecked(1);
             cartInfo.setGoodsBizType(goodsInfo.getGoodsBizType());//业务类型
-            cartInfo.setStockNum(productInfo.getStock_num());
+            cartInfo.setStockNum(stockNum);
             cartInfo.setMerchSn(goodsInfo.getMerchSn());
             cartInfo.setSku(goodsInfo.getSku());
             cartService.save(cartInfo);
         } else {
-            if(number + cartInfo.getNumber() > productInfo.getStock_num()){
+            if(number + cartInfo.getNumber() > stockNum){
                 return toResponsFail("商品选购数量(含购物车已加购数量)已超过库存");
             }
             cartInfo.setNumber(cartInfo.getNumber() + number);
             cartInfo.setGoodsBizType(goodsInfo.getGoodsBizType());//业务类型
-            cartInfo.setStockNum(productInfo.getStock_num());
+            cartInfo.setStockNum(stockNum);
             cartInfo.setSku(goodsInfo.getSku());
             cartService.update(cartInfo);
         }
@@ -336,20 +376,33 @@ public class ApiCartController extends ApiBaseAction {
         Map params = Maps.newHashMap();
         params.put("order_id", orderId);
         List<OrderGoodsVo> orderGoodsVos = apiOrderGoodsService.queryList(params);
+        Integer stockNum = 0;
+        Long storeId = getStoreId();
         for (OrderGoodsVo goodsVo : orderGoodsVos) {
             //判断商品是否可以购买
+            ProductVo productInfo = productService.queryByStoreId(goodsVo.getProduct_id(), storeId);
+            if (null == productInfo) {
+                return toResponsFail("商品已下架");
+            }
             GoodsVo goodsInfo = goodsService.queryObjectByStoreId(goodsVo.getGoods_id(), getStoreId());
             if (null == goodsInfo || goodsInfo.getIs_delete() == 1 || goodsInfo.getIs_on_sale() == 0) {
                 return toResponsFail("商品已下架");
             }
-        }
-        Long storeId = getStoreId();
-        for (OrderGoodsVo goodsVo : orderGoodsVos) {
-            ProductVo productInfo = productService.queryByStoreId(goodsVo.getProduct_id(), storeId);
-            if (null == productInfo) {
-                return toResponsFail("商品已下架");
+            // TODO: 2019/3/5  普通商品不受共享库存影响,直接取门店配置库存
+            if(goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_11.getItem())
+                    || goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_02.getItem())
+                    || goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_10.getItem())){
+                stockNum = productInfo.getStock_num();
+            }
+            if(goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_00.getItem())) {
+                if (goodsInfo.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_1.getItem())) {
+                    stockNum = goodsInfo.getGoods_number();
+                }
+                if (goodsInfo.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_0.getItem())) {
+                    stockNum = productInfo.getStock_num();
+                }
             }
-            if(productInfo.getStock_num() == null || goodsVo.getNumber() > productInfo.getStock_num() || productInfo.getStock_num() <= 0){
+            if(stockNum == null || goodsVo.getNumber() > stockNum || stockNum <= 0){
                 return toResponsFail("该商品库存不足");
             }
             CartVo cartInfo = new CartVo();
@@ -367,7 +420,7 @@ public class ApiCartController extends ApiBaseAction {
             cartInfo.setGoods_specification_ids(goodsVo.getGoods_specification_ids());
             cartInfo.setChecked(1);
             cartInfo.setGoodsBizType(goodsVo.getOrderBizType());
-            cartInfo.setStockNum(productInfo.getStock_num());
+            cartInfo.setStockNum(stockNum);
             cartInfo.setMerchSn(goodsVo.getMerchSn());
             cartInfo.setSku(goodsVo.getSku());
 
@@ -377,6 +430,7 @@ public class ApiCartController extends ApiBaseAction {
             map.put("goods_id",goodsVo.getGoods_id());
             map.put("product_id",goodsVo.getProduct_id());
             map.put("number",goodsVo.getNumber());
+            map.put("isStockShare", goodsInfo.getIsStockShare());
             List<CartVo> list= cartService.queryList(map);
             if(list != null && list.size() > 0){
                 for (CartVo vo:list) {
@@ -401,6 +455,21 @@ public class ApiCartController extends ApiBaseAction {
         Integer goodsId = jsonParam.getInteger("goodsId");
         Integer productId = jsonParam.getInteger("productId");
         Integer number = jsonParam.getInteger("number");
+
+        GoodsVo goodsInfo = goodsService.queryObjectByStoreId(Long.valueOf(goodsId), getStoreId());
+        if (null == goodsInfo || goodsInfo.getIs_delete() == 1 || goodsInfo.getIs_on_sale() == 0) {
+            return toResponsFail("商品已下架");
+        }
+        ThirdMerchantBizVo thirdMerchantBiz = apiThirdMerchantBizService.getThirdMerchangByCode(goodsInfo.getThirdPartyMerchCode());
+        if(null == thirdMerchantBiz){
+            return toResponsFail("商品已下架");
+        }
+        /*if (thirdMerchantBiz.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_1.getItem())){
+            stockNum = goodsInfo.getGoods_number();
+        }
+        if (thirdMerchantBiz.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_0.getItem())){
+            stockNum = productInfo.getStock_num();
+        }*/
         //判断购物车中是否存在此规格商品
         Map cartParam = Maps.newHashMap();
         cartParam.put("goods_id", goodsId);
@@ -408,6 +477,7 @@ public class ApiCartController extends ApiBaseAction {
         Long storeId = getStoreId();
         cartParam.put("store_id", storeId);
         cartParam.put("user_id", loginUser.getId());
+        cartParam.put("isStockShare", thirdMerchantBiz.getIsStockShare());
         List<CartVo> cartInfoList = cartService.queryList(cartParam);
         CartVo cartInfo = null != cartInfoList && cartInfoList.size() > 0 ? cartInfoList.get(0) : null;
         int cart_num = 0;
@@ -437,12 +507,35 @@ public class ApiCartController extends ApiBaseAction {
         Integer id = jsonParam.getInteger("id");
         String checkCart = jsonParam.getString("checkCart");
         boolean isAdd = true;
+        Integer stockNum = 0;
+        GoodsVo goodsInfo = goodsService.queryObjectByStoreId(Long.valueOf(goodsId), getStoreId());
+        if (null == goodsInfo || goodsInfo.getIs_delete() == 1 || goodsInfo.getIs_on_sale() == 0) {
+            return toResponsFail("商品已下架");
+        }
         //取得规格的信息,判断规格库存
         ProductVo productInfo = productService.queryByStoreId(productId, storeId);
         if (null == productInfo) {
             return this.toResponsObject(400, "商品已下架", getCart(checkCart));
         }
-        if(productInfo.getStock_num() == null || number > productInfo.getStock_num() || productInfo.getStock_num() <= 0){
+        ThirdMerchantBizVo thirdMerchantBiz = apiThirdMerchantBizService.getThirdMerchangByCode(goodsInfo.getThirdPartyMerchCode());
+        if(null == thirdMerchantBiz){
+            return toResponsFail("商品已下架");
+        }
+        // TODO: 2019/3/5  普通商品不受共享库存影响,直接取门店配置库存
+        if(goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_11.getItem())
+                || goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_02.getItem())
+                || goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_10.getItem())){
+            stockNum = productInfo.getStock_num();//门店库存
+        }
+        if(goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_00.getItem())){
+            if (thirdMerchantBiz.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_1.getItem())){
+                stockNum = goodsInfo.getGoods_number();
+            }
+            if (thirdMerchantBiz.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_0.getItem())){
+                stockNum = productInfo.getStock_num();
+            }
+        }
+        if(stockNum == null || number > stockNum || stockNum <= 0){
             return this.toResponsObject(400, "该商品库存不足", getCart(checkCart));
         }
         String msg = "";
@@ -456,7 +549,7 @@ public class ApiCartController extends ApiBaseAction {
         //只是更新number
         if (cartInfo.getProduct_id().equals(productId)) {
             cartInfo.setNumber(number);
-            cartInfo.setStockNum(productInfo.getStock_num());
+            cartInfo.setStockNum(stockNum);
             cartService.update(cartInfo);
             return toResponsObject(0, msg, getCart(checkCart));
         }
@@ -465,6 +558,7 @@ public class ApiCartController extends ApiBaseAction {
         cartParam.put("goodsId", goodsId);
         cartParam.put("productId", productId);
         cartParam.put("store_id", storeId);
+        cartParam.put("isStockShare", thirdMerchantBiz.getIsStockShare());
         List<CartVo> cartInfoList = cartService.queryList(cartParam);
         CartVo newcartInfo = null != cartInfoList && cartInfoList.size() > 0 ? cartInfoList.get(0) : null;
         if (null == newcartInfo) {
@@ -544,6 +638,7 @@ public class ApiCartController extends ApiBaseAction {
         Map param = Maps.newHashMap();
         param.put("user_id", loginUser.getId());
         param.put("store_id", getStoreId());
+        param.putAll(setIsStockShare(getStoreId()));
         List<CartVo> cartList = cartService.queryList(param);
         //获取购物车统计信息
         Integer goodsCount = 0;
@@ -702,6 +797,7 @@ public class ApiCartController extends ApiBaseAction {
         param.put("user_id", loginUser.getId());
         Long storeId = getStoreId();
         param.put("store_id", storeId);
+        param.putAll(setIsStockShare(storeId));
         List<CartVo> cartList = cartService.queryList(param);
         //获取购物车统计信息
         BigDecimal checkedGoodsAmount = new BigDecimal(0.00);

+ 7 - 2
kmall-api/src/main/java/com/kmall/api/api/ApiFootprintController.java

@@ -107,7 +107,9 @@ public class ApiFootprintController extends ApiBaseAction {
      * 猜你喜欢
      */
     @GetMapping("glist")
-    public Object glist(@LoginUser UserVo loginUser,String storeId,String checkCart) {
+    public Object glist(@LoginUser UserVo loginUser,String storeId,String checkCart,
+                        @RequestParam(value = "page", defaultValue = "1") Integer
+                                page, @RequestParam(value = "size", defaultValue = "4") Integer size) {
         Map resultObj = Maps.newHashMap();
 
         //查询列表数据
@@ -119,7 +121,10 @@ public class ApiFootprintController extends ApiBaseAction {
         params.put("bizType", true);
         params.put("store_id", storeId);
         params.put("checkCart", checkCart);
-        List<FootprintVo> footprintVos = footprintService.queryList(params);
+        params.put("page", page);
+        params.put("limit", size);
+        Query query = new Query(params);
+        List<FootprintVo> footprintVos = footprintService.queryList(query);
         List<FootprintVo> list = new ArrayList();
         if (null != footprintVos) {
             for (FootprintVo vo : footprintVos) {

+ 81 - 9
kmall-api/src/main/java/com/kmall/api/api/ApiGoodsController.java

@@ -7,6 +7,7 @@ import com.kmall.api.entity.*;
 import com.kmall.api.service.*;
 import com.kmall.api.util.ApiBaseAction;
 import com.kmall.api.util.ApiPageUtils;
+import com.kmall.common.constant.Dict;
 import com.kmall.common.utils.DateUtils;
 import com.kmall.common.utils.Query;
 import com.kmall.common.utils.enums.CouponTypeEnum;
@@ -71,6 +72,10 @@ public class ApiGoodsController extends ApiBaseAction {
 
     @Autowired
     private ApiFreightService apiFreightService;
+    @Autowired
+    private ApiThirdMerchantBizService apiThirdMerchantBizService;
+    @Autowired
+    private ApiStoreService apiStoreService;
 
     /**
      */
@@ -209,10 +214,24 @@ public class ApiGoodsController extends ApiBaseAction {
         Map cartMap= Maps.newHashMap();
         cartMap.put("user_id",userId);
         cartMap.put("goods_id",info.getId());
+        cartMap.put("store_id", storeId);
+        cartMap.put("isStockShare", info.getIsStockShare());
         List<CartVo> cartVoList = cartService.queryList(cartMap);
 
         FreightEntity freightEntity = apiFreightService.queryObjectByGoodsId(info.getId(), getStoreId());
-        //
+
+        Integer stockNum = 0;
+        if(info.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_00.getItem())){
+            if (info.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_1.getItem())) {
+                stockNum = info.getGoods_number();
+                info.setSell_volume(info.getGoods_sell_volume());
+            }
+            if (info.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_0.getItem())) {
+                stockNum = info.getStockNum();
+            }
+        }else {
+            stockNum = info.getStockNum();
+        }
         resultObj.put("info", info);
 
         resultObj.put("attribute", attribute);
@@ -221,7 +240,7 @@ public class ApiGoodsController extends ApiBaseAction {
         resultObj.put("comment", comment);
         resultObj.put("specificationList", specificationList);
         resultObj.put("productList", productEntityList);
-        resultObj.put("stockNum", productEntityList.size()!=0? productEntityList.get(0).getStock_num():0);
+        resultObj.put("stockNum", stockNum);
         resultObj.put("cartNumber", cartVoList.size()!=0? cartVoList.get(0).getNumber():0);
         resultObj.put("defaultFreight", freightEntity != null? freightEntity.getDefaultFreight() :0);
 
@@ -334,14 +353,14 @@ public class ApiGoodsController extends ApiBaseAction {
         params.put("is_hot", isHot);
         params.put("page", page);
         params.put("limit", size);
-        params.put("order", sort);
-        params.put("sidx", order);
+//        params.put("order", sort);
+//        params.put("sidx", order);
         params.put("goodsBizType", goodsBizType);
         params.put("store_id", getStoreId());
         params.put("notGoodsBizType", true);
         //
         if (null != sort && sort.equals("price")) {
-            params.put("sidx", "a.retail_price");
+            params.put("sidx", "psr1.retail_price");
             params.put("order", order);
         } else {
             params.put("sidx", "a.id");
@@ -422,10 +441,20 @@ public class ApiGoodsController extends ApiBaseAction {
     @IgnoreAuth
     @GetMapping("hotGoodsList")
     public Object hotGoodsList(@LoginUser UserVo loginUser, Integer categoryId,
+                               @RequestParam(value = "page", defaultValue = "1") Integer
+                                       page, @RequestParam(value = "size", defaultValue = "10") Integer size,
                                String sort, String order) {
         Map reusltObj = Maps.newHashMap();
         //
         Long store_id = getStoreId();
+        StoreVo storeVo = apiStoreService.queryObject(store_id);
+        ThirdMerchantBizVo thirdMerchantBiz = new ThirdMerchantBizVo();
+        if(storeVo != null) {
+            thirdMerchantBiz = apiThirdMerchantBizService.getThirdMerchangByCode(storeVo.getThirdPartyMerchCode());
+            if (null == thirdMerchantBiz) {
+                return toResponsFail("第三方商户为空");
+            }
+        }
         Map params = Maps.newHashMap();
         //筛选的分类
         List<CategoryVo> filterCategory = new ArrayList();
@@ -472,7 +501,7 @@ public class ApiGoodsController extends ApiBaseAction {
         }
         params.put("category_parent_id", categoryId);
         params.put("fields", "a.id,a.name,a.goods_brief,a.list_pic_url,psr1.retail_price," +
-                "psr1.market_price,b.id as product_id");
+                "psr1.market_price,b.id as product_id,psr1.stock_num");
         params.put("is_hot", "1");
         params.put("is_delete", 0);
         params.put("store_id", store_id);
@@ -482,9 +511,34 @@ public class ApiGoodsController extends ApiBaseAction {
                 params.put("order", order);
             }
         }
-        List<GoodsVo> hotGoods = goodsService.queryHotGoodsList(params);
 
         reusltObj.put("filterCategory", filterCategory);
+        params.put("isStockShare", thirdMerchantBiz.getIsStockShare());
+
+        params.put("page", page);
+        params.put("limit", size);
+        Query query = new Query(params);
+        List<GoodsVo> hotGoods = goodsService.queryHotGoodsList(query);
+        // 当前购物车中
+        List<CartVo> cartList = new ArrayList();
+        if (null != getUserId()) {
+            //查询列表数据
+            Map cartParam = Maps.newHashMap();
+            cartParam.put("user_id", getUserId());
+            cartParam.put("store_id", getStoreId());
+            cartParam.put("isStockShare", thirdMerchantBiz.getIsStockShare());
+
+            cartList = cartService.queryList(cartParam);
+        }
+        if (null != cartList && cartList.size() > 0 && null != hotGoods && hotGoods.size() > 0) {
+            for (GoodsVo goodsVo : hotGoods) {
+                for (CartVo cartVo : cartList) {
+                    if (goodsVo.getId().equals(cartVo.getGoods_id())) {
+                        goodsVo.setCart_num(cartVo.getNumber());
+                    }
+                }
+            }
+        }
         reusltObj.put("goodsList", hotGoods);
 
         return toResponsSuccess(reusltObj);
@@ -537,7 +591,9 @@ public class ApiGoodsController extends ApiBaseAction {
      */
     @IgnoreAuth
     @GetMapping("related")
-    public Object related(@LoginUser UserVo loginUser, Long id) {
+    public Object related(@LoginUser UserVo loginUser, Long id,
+                          @RequestParam(value = "page", defaultValue = "1") Integer
+                                  page, @RequestParam(value = "size", defaultValue = "4") Integer size) {
         Map<String, Object> resultObj = Maps.newHashMap();
         Map param = Maps.newHashMap();
         param.put("goods_id", id);
@@ -558,6 +614,10 @@ public class ApiGoodsController extends ApiBaseAction {
                 paramRelated.put("notGoodsBizType", true);
                 paramRelated.put("fields", "a.id, a.name, a.list_pic_url, psr1.retail_price,b.id as product_id");
                 paramRelated.put("category_id", goodsCategory.getCategory_id());
+                paramRelated.put("limit", size);
+                paramRelated.put("offset", (page - 1) * size);
+                paramRelated.put("sidx", "a.create_time");
+                paramRelated.put("order", "desc");
                 relatedGoods = goodsService.queryList(paramRelated);
             }
         } else {
@@ -566,6 +626,10 @@ public class ApiGoodsController extends ApiBaseAction {
             paramRelated.put("notGoodsBizType", true);
             paramRelated.put("goods_ids", relatedGoodsIds);
             paramRelated.put("fields", "a.id, a.name, a.list_pic_url, psr1.retail_price,b.id as product_id");
+            paramRelated.put("limit", size);
+            paramRelated.put("offset", (page - 1) * size);
+            paramRelated.put("sidx", "a.create_time");
+            paramRelated.put("order", "desc");
             relatedGoods = goodsService.queryList(paramRelated);
         }
         resultObj.put("goodsList", relatedGoods);
@@ -608,7 +672,7 @@ public class ApiGoodsController extends ApiBaseAction {
         params.put("store_id", getStoreId());
         //
         if (null != sort && sort.equals("price")) {
-            params.put("sidx", "retail_price");
+            params.put("sidx", "psr1.retail_price");
             params.put("order", order);
         } else if (null != sort && sort.equals("sell")) {
             params.put("sidx", "psr1.sell_volume");
@@ -644,6 +708,14 @@ public class ApiGoodsController extends ApiBaseAction {
             Map cartParam = Maps.newHashMap();
             cartParam.put("user_id", getUserId());
             cartParam.put("store_id", storeId);
+            StoreVo storeVo = apiStoreService.queryObject(storeId);
+            if(storeVo != null) {
+                ThirdMerchantBizVo thirdMerchantBiz = apiThirdMerchantBizService.getThirdMerchangByCode(storeVo.getThirdPartyMerchCode());
+                if (null == thirdMerchantBiz) {
+                    return toResponsFail("第三方商户为空");
+                }
+                cartParam.put("isStockShare", thirdMerchantBiz.getIsStockShare());
+            }
             cartList = cartService.queryList(cartParam);
         }
         if (null != cartList && cartList.size() > 0 && null != goodsList && goodsList.size() > 0) {

+ 5 - 28
kmall-api/src/main/java/com/kmall/api/api/ApiIndexController.java

@@ -48,6 +48,10 @@ public class ApiIndexController extends ApiBaseAction {
     private ApiOrderService apiOrderService;
     @Autowired
     private ApiUserService apiUserService;
+    @Autowired
+    private ApiThirdMerchantBizService apiThirdMerchantBizService;
+    @Autowired
+    private ApiStoreService apiStoreService;
 
     /**
      * app首页
@@ -83,34 +87,7 @@ public class ApiIndexController extends ApiBaseAction {
         param.put("order", "asc ");
         List<ChannelVo> channel = channelService.queryList(param);
         resultObj.put("channel", channel);
-        // 超级折扣,需要门店过滤
-        param = Maps.newHashMap();
-        param.put("fields", "distinct a.id,a.name,a.goods_brief,a.list_pic_url,psr1.retail_price,psr1.market_price,b.id as product_id,psr1.stock_num");
-        param.put("is_hot", "1");
-        param.put("offset", 0);
-        param.put("limit", 20);
-        param.put("is_delete", 0);
-        param.put("store_id", storeId);
-        List<GoodsVo> hotGoods = goodsService.queryHotGoodsList(param);
-        resultObj.put("hotGoodsList", hotGoods);
-        // 当前购物车中
-        List<CartVo> cartList = new ArrayList();
-        if (null != userId) {
-            //查询列表数据
-            Map cartParam = Maps.newHashMap();
-            cartParam.put("user_id", userId);
-            cartParam.put("store_id", storeId);
-            cartList = cartService.queryList(cartParam);
-        }
-        if (null != cartList && cartList.size() > 0 && null != hotGoods && hotGoods.size() > 0) {
-            for (GoodsVo goodsVo : hotGoods) {
-                for (CartVo cartVo : cartList) {
-                    if (goodsVo.getId().equals(cartVo.getGoods_id())) {
-                        goodsVo.setCart_num(cartVo.getNumber());
-                    }
-                }
-            }
-        }
+
         return toResponsSuccess(resultObj);
     }
 

+ 7 - 0
kmall-api/src/main/java/com/kmall/api/dao/ApiGoodsMapper.java

@@ -21,4 +21,11 @@ public interface ApiGoodsMapper extends BaseDao<GoodsVo> {
     List<GoodsVo> queryCatalogProductList(Map<String, Object> params);
 
     GoodsVo queryObjectByStoreId(@Param("id") Long id, @Param("storeId") Long storeId);
+
+    /**
+     * 更新共享库存
+     *
+     * @return
+     */
+    void updateGoodsStock(GoodsVo goodsVo);
 }

+ 6 - 0
kmall-api/src/main/java/com/kmall/api/dao/ApiProductMapper.java

@@ -12,6 +12,12 @@ import org.springframework.stereotype.Component;
  */
 @Component
 public interface ApiProductMapper extends BaseDao<ProductVo> {
+    /**
+     * 暂时无用
+     * @param id
+     * @param store_id
+     * @return
+     */
     ProductVo queryObjectByStoreId(@Param("id") Long id, @Param("store_id") Long store_id);
 
     /**

+ 20 - 0
kmall-api/src/main/java/com/kmall/api/dao/ApiThirdMerchantBizMapper.java

@@ -0,0 +1,20 @@
+package com.kmall.api.dao;
+
+import com.kmall.api.entity.GoodsVo;
+import com.kmall.api.entity.ThirdMerchantBizVo;
+import com.kmall.common.dao.BaseDao;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Scott
+ * @email
+ * @date 2017-08-11 09:16:45
+ */
+@Component
+public interface ApiThirdMerchantBizMapper extends BaseDao<ThirdMerchantBizVo> {
+    ThirdMerchantBizVo getThirdMerchangByCode(@Param("thirdMerchantCode")String thirdMerchantCode);
+}

+ 20 - 0
kmall-api/src/main/java/com/kmall/api/entity/CartVo.java

@@ -68,6 +68,26 @@ public class CartVo implements Serializable {
 
     private String merchSn;
 
+    private Integer goodsNumber;
+
+    private String isStockShare;
+
+    public String getIsStockShare() {
+        return isStockShare;
+    }
+
+    public void setIsStockShare(String isStockShare) {
+        this.isStockShare = isStockShare;
+    }
+
+    public Integer getGoodsNumber() {
+        return goodsNumber;
+    }
+
+    public void setGoodsNumber(Integer goodsNumber) {
+        this.goodsNumber = goodsNumber;
+    }
+
     public String getMerchSn() {
         return merchSn;
     }

+ 49 - 1
kmall-api/src/main/java/com/kmall/api/entity/GoodsVo.java

@@ -57,8 +57,10 @@ public class GoodsVo implements Serializable {
     private BigDecimal market_price;
     //零售价格(现价)
     private BigDecimal retail_price;
-    //销售量
+    //门店销售量
     private Integer sell_volume;
+    //商品销售量
+    private Integer goods_sell_volume;
     //主sku product_id
     private Integer primary_product_id;
     //单位价格,单价
@@ -109,6 +111,52 @@ public class GoodsVo implements Serializable {
 
     private String merchName;
 
+    /**
+     * 第三方商户代码
+     */
+    private String thirdPartyMerchCode;
+
+    private String isStockShare;
+
+    public void addSellVolume() {
+        if (null == sell_volume) {
+            sell_volume = 1;
+        } else {
+            sell_volume++;
+        }
+    }
+
+    public void minusSellVolume() {
+        if (null == sell_volume || 0 == sell_volume) {
+            sell_volume = 0;
+        } else {
+            sell_volume--;
+        }
+    }
+    public Integer getGoods_sell_volume() {
+        return goods_sell_volume;
+    }
+
+    public void setGoods_sell_volume(Integer goods_sell_volume) {
+        this.goods_sell_volume = goods_sell_volume;
+    }
+
+    public String getThirdPartyMerchCode() {
+        return thirdPartyMerchCode;
+    }
+
+    public void setThirdPartyMerchCode(String thirdPartyMerchCode) {
+        this.thirdPartyMerchCode = thirdPartyMerchCode;
+    }
+
+    public String getIsStockShare() {
+        return isStockShare;
+    }
+
+    public void setIsStockShare(String isStockShare) {
+        this.isStockShare = isStockShare;
+    }
+
     public Integer getStoreId() {
         return storeId;
     }

+ 203 - 0
kmall-api/src/main/java/com/kmall/api/entity/ThirdMerchantBizVo.java

@@ -0,0 +1,203 @@
+package com.kmall.api.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 第三方商户表实体
+ * 表名 third_merchant_biz
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2019-02-15 11:43:32
+ */
+public class ThirdMerchantBizVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 第三方商户编号,主键编号
+     */
+    private Integer thirdMerchSn;
+
+    private String merchSn;
+    /**
+     * 第三方商户代码
+     */
+    private String thirdPartyMerchCode;
+    /**
+     * 第三方商户名称
+     */
+    private String thirdPartyMerchName;
+
+    private String isStockShare;
+
+    private String isStoreUserShare;
+
+
+    /**
+     * 是否有效,0:有效,1:无效
+     */
+    private String isValid;
+    /**
+     * 创建人序号
+     */
+    private String createrSn;
+    /**
+     * 创建时间,yyyy-MM-dd HH:mm:ss
+     */
+    private Date createTime;
+    /**
+     * 
+     */
+    private String moderSn;
+    /**
+     * 修改时间,yyyy-MM-dd HH:mm:ss
+     */
+    private Date modTime;
+    /**
+     * 时间戳
+     */
+    private Date tstm;
+
+    public String getIsStoreUserShare() {
+        return isStoreUserShare;
+    }
+
+    public void setIsStoreUserShare(String isStoreUserShare) {
+        this.isStoreUserShare = isStoreUserShare;
+    }
+
+    public String getIsStockShare() {
+        return isStockShare;
+    }
+
+    public void setIsStockShare(String isStockShare) {
+        this.isStockShare = isStockShare;
+    }
+
+    public String getMerchSn() {
+        return merchSn;
+    }
+
+    public void setMerchSn(String merchSn) {
+        this.merchSn = merchSn;
+    }
+
+    /**
+     * 设置:第三方商户编号,主键编号
+     */
+    public void setThirdMerchSn(Integer thirdMerchSn) {
+        this.thirdMerchSn = thirdMerchSn;
+    }
+
+    /**
+     * 获取:第三方商户编号,主键编号
+     */
+    public Integer getThirdMerchSn() {
+        return thirdMerchSn;
+    }
+    /**
+     * 设置:第三方商户代码
+     */
+    public void setThirdPartyMerchCode(String thirdPartyMerchCode) {
+        this.thirdPartyMerchCode = thirdPartyMerchCode;
+    }
+
+    /**
+     * 获取:第三方商户代码
+     */
+    public String getThirdPartyMerchCode() {
+        return thirdPartyMerchCode;
+    }
+    /**
+     * 设置:第三方商户名称
+     */
+    public void setThirdPartyMerchName(String thirdPartyMerchName) {
+        this.thirdPartyMerchName = thirdPartyMerchName;
+    }
+
+    /**
+     * 获取:第三方商户名称
+     */
+    public String getThirdPartyMerchName() {
+        return thirdPartyMerchName;
+    }
+    /**
+     * 设置:是否有效,0:有效,1:无效
+     */
+    public void setIsValid(String isValid) {
+        this.isValid = isValid;
+    }
+
+    /**
+     * 获取:是否有效,0:有效,1:无效
+     */
+    public String getIsValid() {
+        return isValid;
+    }
+    /**
+     * 设置:创建人序号
+     */
+    public void setCreaterSn(String createrSn) {
+        this.createrSn = createrSn;
+    }
+
+    /**
+     * 获取:创建人序号
+     */
+    public String getCreaterSn() {
+        return createrSn;
+    }
+    /**
+     * 设置:创建时间,yyyy-MM-dd HH:mm:ss
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * 获取:创建时间,yyyy-MM-dd HH:mm:ss
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+    /**
+     * 设置:
+     */
+    public void setModerSn(String moderSn) {
+        this.moderSn = moderSn;
+    }
+
+    /**
+     * 获取:
+     */
+    public String getModerSn() {
+        return moderSn;
+    }
+    /**
+     * 设置:修改时间,yyyy-MM-dd HH:mm:ss
+     */
+    public void setModTime(Date modTime) {
+        this.modTime = modTime;
+    }
+
+    /**
+     * 获取:修改时间,yyyy-MM-dd HH:mm:ss
+     */
+    public Date getModTime() {
+        return modTime;
+    }
+    /**
+     * 设置:时间戳
+     */
+    public void setTstm(Date tstm) {
+        this.tstm = tstm;
+    }
+
+    /**
+     * 获取:时间戳
+     */
+    public Date getTstm() {
+        return tstm;
+    }
+}

+ 81 - 18
kmall-api/src/main/java/com/kmall/api/service/ApiOrderService.java

@@ -106,9 +106,37 @@ public class ApiOrderService {
         List<OrderGoodsVo> goodsList = apiOrderGoodsMapper.queryList(orderGoodsParam);
         for (OrderGoodsVo orderGoodsVo : goodsList) {
             ProductVo productInfo = apiProductMapper.queryByStoreId(orderGoodsVo.getProduct_id(), order.getStore_id());
-            productInfo.setStock_num(productInfo.getStock_num() + orderGoodsVo.getNumber());
-            productInfo.minusSellVolume();
-            apiProductMapper.updateStockNum(productInfo);
+
+            GoodsVo goodsInfo = apiGoodsMapper.queryObjectByStoreId(orderGoodsVo.getGoods_id(), order.getStore_id());
+            if (null == goodsInfo || goodsInfo.getIs_delete() == 1 || goodsInfo.getIs_on_sale() == 0) {
+                throw new RRException("订单提交失败:商品不存在");
+            }
+            Integer stockNum = 0;
+            // TODO: 2019/3/5  普通商品不受共享库存影响,直接取门店配置库存
+            if(goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_00.getItem())){
+                if (goodsInfo.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_1.getItem())) {
+                    //还原商户商品库存
+                    stockNum = goodsInfo.getGoods_number();
+                    goodsInfo.setGoods_number(stockNum + orderGoodsVo.getNumber());
+                    goodsInfo.minusSellVolume();
+                    apiGoodsMapper.updateGoodsStock(goodsInfo);
+                }
+                if (goodsInfo.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_0.getItem())) {
+                    //还原门店库存
+                    stockNum = productInfo.getStock_num();
+                    productInfo.setStock_num(stockNum + orderGoodsVo.getNumber());
+                    productInfo.minusSellVolume();
+                    productInfo.setGoods_id(goodsInfo.getId());
+                    apiProductMapper.updateStockNum(productInfo);
+                }
+            }else {
+                //还原门店库存
+                stockNum = productInfo.getStock_num();
+                productInfo.setStock_num(stockNum + orderGoodsVo.getNumber());
+                productInfo.setGoods_id(goodsInfo.getId());
+                productInfo.minusSellVolume();
+                apiProductMapper.updateStockNum(productInfo);
+            }
         }
         update(order);
         // 判断是否有优惠券
@@ -200,21 +228,47 @@ public class ApiOrderService {
             return resultObj;
         }
         // 检查库存和更新库存
-        List<ProductVo> productVos = new ArrayList();
+//        List<ProductVo> productVos = new ArrayList();
         for (CartVo goodsItem : checkedGoodsList) {
+            Integer stockNum = 0;
             //取得规格的信息,判断规格库存
+            GoodsVo goodsInfo = apiGoodsMapper.queryObjectByStoreId(goodsItem.getGoods_id(), storeId);
+            if (null == goodsInfo || goodsInfo.getIs_delete() == 1 || goodsInfo.getIs_on_sale() == 0) {
+                throw new RRException("订单提交失败:商品不存在");
+            }
             ProductVo productInfo = apiProductMapper.queryByStoreId(goodsItem.getProduct_id(), storeId);
+
             synchronized (productInfo){
-                if (null == productInfo || null == productInfo.getStock_num() || productInfo.getStock_num() < goodsItem.getNumber()) {
-                    resultObj.put("errno", 400);
-                    resultObj.put("errmsg", "库存不足,仅剩余" + productInfo.getStock_num());
-                    return resultObj;
+                if (null == productInfo) {
+                    throw new RRException("订单提交失败:商品已下架");
+                }
+                // TODO: 2019/3/5  普通商品不受共享库存影响,直接取门店配置库存
+                if(goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_00.getItem())){
+                    if (goodsInfo.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_1.getItem())) {
+                        stockNum = goodsInfo.getGoods_number();
+                    }
+                    if (goodsInfo.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_0.getItem())) {
+                        stockNum = productInfo.getStock_num();
+                    }
+                }else {
+                    stockNum = productInfo.getStock_num();
+                }
+                if (null == stockNum || stockNum < goodsItem.getNumber() || stockNum <= 0) {
+                    throw new RRException("订单提交失败:库存不足,仅剩余" + stockNum);
                 }else{
-                    productInfo.setStock_num(productInfo.getStock_num() - goodsItem.getNumber());
-                    productInfo.setStore_id(storeId);
-                    productInfo.addSellVolume();
-                    productVos.add(productInfo);
-                    apiProductMapper.updateStockNum(productInfo);
+                    if(goodsInfo.getGoodsBizType().equalsIgnoreCase(Dict.orderBizType.item_00.getItem())){
+                        if (goodsInfo.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_1.getItem())) {
+                            //扣减商户商品库存
+                            updateGoodsStock(goodsInfo,stockNum,goodsItem);
+                        }
+                        if (goodsInfo.getIsStockShare().equalsIgnoreCase(Dict.isStockShare.item_0.getItem())) {
+                            //扣减门店库存
+                            updateStock(productInfo,goodsInfo,stockNum,goodsItem,storeId);
+                        }
+                    }else {
+                        //扣减门店库存
+                        updateStock(productInfo,goodsInfo,stockNum,goodsItem,storeId);
+                    }
                 }
             }
         }
@@ -381,6 +435,20 @@ public class ApiOrderService {
 
         return resultObj;
     }
+    private void updateGoodsStock(GoodsVo goodsVo,Integer stockNum,CartVo goodsItem){
+        goodsVo.setGoods_number(stockNum - goodsItem.getNumber());
+        goodsVo.addSellVolume();
+        goodsVo.setId(goodsVo.getId());
+        apiGoodsMapper.updateGoodsStock(goodsVo);
+    }
+    private void updateStock(ProductVo productInfo,GoodsVo goodsVo,Integer stockNum,CartVo goodsItem,Long storeId){
+        productInfo.setStock_num(stockNum - goodsItem.getNumber());
+        productInfo.setStore_id(storeId);
+        productInfo.addSellVolume();
+        productInfo.setGoods_id(goodsVo.getId());
+//        productVos.add(productInfo);
+        apiProductMapper.updateStockNum(productInfo);
+    }
 
     /**
      * 设置订单数据
@@ -557,23 +625,18 @@ public class ApiOrderService {
         if(orderInfo.getFreight_price()!=0 && !"0".equalsIgnoreCase(orderInfo.getCoupon_price()+"")){
             //运费-优惠券
             BigDecimal rateTotal = freightPrice.subtract(orderInfo.getCoupon_price());
-
             //商品结算平摊价格(含优惠券、运费金额) = 单商品总价 + 单商品总价/订单总价(不含运费、不含优惠券) * 运费与优惠券合计税率
             settlePrice = goodsTotal.add(rate.multiply(rateTotal));
         }else{
             if(orderInfo.getFreight_price()!=0){
                 //运费税率 = 单商品总价/订单总价(不含运费)* 运费金额
                 BigDecimal freightRate = rate.multiply(freightPrice);
-
                 //商品结算平摊价格(含运费金额) = 单商品总价+运费税率
                 settlePrice = goodsTotal.add(freightRate);
-
             }
             if(!"0".equalsIgnoreCase(orderInfo.getCoupon_price()+"")){
-
                 //优惠券税率 = 单商品总价/订单总价(不含优惠券)* 优惠券金额
                 BigDecimal couponRate = rate.multiply(orderInfo.getCoupon_price());
-
                 //商品结算平摊价格(含优惠券金额) = 单商品总价-优惠券税率
                 settlePrice = goodsTotal.subtract(couponRate);
             }

+ 62 - 0
kmall-api/src/main/java/com/kmall/api/service/ApiThirdMerchantBizService.java

@@ -0,0 +1,62 @@
+package com.kmall.api.service;
+
+import com.kmall.api.dao.ApiFreightMapper;
+import com.kmall.api.dao.ApiThirdMerchantBizMapper;
+import com.kmall.api.entity.FreightEntity;
+import com.kmall.api.entity.ThirdMerchantBizVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Service实现类
+ *
+ * @author
+ */
+@Service
+public class ApiThirdMerchantBizService {
+    @Autowired
+    private ApiThirdMerchantBizMapper thirdMerchantBizMapper;
+
+    
+    public ThirdMerchantBizVo queryObject(Integer id) {
+        return thirdMerchantBizMapper.queryObject(id);
+    }
+
+    
+    public List<ThirdMerchantBizVo> queryList(Map<String, Object> map) {
+        return thirdMerchantBizMapper.queryList(map);
+    }
+
+    
+    public int queryTotal(Map<String, Object> map) {
+        return thirdMerchantBizMapper.queryTotal(map);
+    }
+
+    
+    public int save(ThirdMerchantBizVo thirdMerchantBizVo) {
+        return thirdMerchantBizMapper.save(thirdMerchantBizVo);
+    }
+
+    
+    public int update(ThirdMerchantBizVo thirdMerchantBizVo) {
+        return thirdMerchantBizMapper.update(thirdMerchantBizVo);
+    }
+
+    
+    public int delete(Integer id) {
+        return thirdMerchantBizMapper.delete(id);
+    }
+
+    
+    public int deleteBatch(Integer[]ids) {
+        return thirdMerchantBizMapper.deleteBatch(ids);
+    }
+
+
+    public ThirdMerchantBizVo getThirdMerchangByCode(String thirdMerchantCode) {
+        return thirdMerchantBizMapper.getThirdMerchangByCode(thirdMerchantCode);
+    }
+}

+ 32 - 4
kmall-api/src/main/resources/mybatis/mapper/ApiCartMapper.xml

@@ -28,6 +28,8 @@
         <result column="tstm" property="tstm" jdbcType="TIMESTAMP" />
         <result property="stockNum" column="productStockNum"/>
         <result property="merchSn" column="merch_sn"/>
+        <result property="goodsNumber" column="goods_number"/>
+
     </resultMap>
 
     <sql id="Base_Column_List" >
@@ -50,13 +52,23 @@
     <select id="queryList" resultMap="cartMap">
         select a.*,
         b.list_pic_url as list_pic_url,
-        psr.retail_price as retail_product_price,psr.stock_num 'productStockNum'
+        psr.retail_price as retail_product_price,psr.stock_num 'productStockNum',
+        b.goods_number,mb.is_stock_share isStockShare
         from mall_cart a
         left join mall_goods b on a.goods_id = b.id
+        left join third_merchant_biz mb on b.third_party_merch_code = mb.third_party_merch_code and mb.merch_sn=b.merch_sn
         left join mall_product c on c.goods_id = a.goods_id and c.id = a.product_id
         left join mall_product_store_rela psr on psr.product_id = c.id and psr.store_id = #{store_id}
         where 1 = 1  and b.is_delete = 0 and b.is_on_sale = 1
-        and psr.stock_num > 0
+        <if test="isStockShare == 1 and checkCart != null and checkCart == '00'">
+            and b.goods_number > 0
+        </if>
+        <if test="isStockShare == 0 and checkCart != null and checkCart == '00'">
+            and psr.stock_num > 0
+        </if>
+        <if test="checkCart != null and checkCart == '11'">
+            and psr.stock_num > 0
+        </if>
         <if test="checkCart != null and checkCart == '00'">
             and b.goods_biz_type != '11'
         </if>
@@ -101,7 +113,15 @@
         left join mall_product c on c.goods_id = a.goods_id and c.id = a.product_id
         left join mall_product_store_rela psr on psr.product_id = c.id and psr.store_id = #{store_id}
         where 1 = 1
-        and (psr.stock_num = 0 or b.is_on_sale = 0)
+        <if test="isStockShare == 1 and checkCart != null and checkCart == '00'">
+            and (b.goods_number = 0 or b.is_on_sale = 0)
+        </if>
+        <if test="isStockShare == 0 and checkCart != null and checkCart == '00'">
+            and (psr.stock_num = 0 or b.is_on_sale = 0)
+        </if>
+        <if test="checkCart != null and checkCart == '11'">
+            and (psr.stock_num = 0 or b.is_on_sale = 0)
+        </if>
         <if test="checkCart != null and checkCart == '00'">
             and b.goods_biz_type != '11'
         </if>
@@ -146,7 +166,15 @@
         left join mall_product c on c.goods_id = a.goods_id and c.id = a.product_id
         left join mall_product_store_rela psr on psr.product_id = c.id and psr.store_id = #{store_id}
         where 1 = 1  and b.is_delete = 0 and b.is_on_sale = 1
-        and psr.stock_num > 0
+        <if test="isStockShare == 1 and checkCart != null and checkCart == '00'">
+            and b.goods_number > 0
+        </if>
+        <if test="isStockShare == 0 and checkCart != null and checkCart == '00'">
+            and psr.stock_num > 0
+        </if>
+        <if test="checkCart != null and checkCart == '11'">
+            and psr.stock_num > 0
+        </if>
         <if test="checkCart != null and checkCart == '00'">
             and b.goods_biz_type != '11'
         </if>

+ 50 - 10
kmall-api/src/main/resources/mybatis/mapper/ApiGoodsMapper.xml

@@ -49,6 +49,10 @@
         <result property="storeId" column="store_id"/>
         <result property="merchSn" column="merch_sn"/>
         <result property="merchName" column="merch_name"/>
+        <result column="third_party_merch_code" property="thirdPartyMerchCode" />
+        <result column="isStockShare" property="isStockShare" />
+        <result property="goods_sell_volume" column="goods_sell_volume"/>
+
     </resultMap>
 
     <sql id="Base_Column_List" >
@@ -57,7 +61,7 @@
         extra_price, is_new, goods_unit, primary_pic_url, list_pic_url, retail_price, sell_volume,
         primary_product_id, unit_price, promotion_desc, promotion_tag, app_exclusive_price,
         is_app_exclusive, is_limited, is_hot, market_price, creater_sn, create_time, moder_sn,
-        mod_time, tstm,goods_desc,goods_rate
+        mod_time, tstm,goods_desc,goods_rate,third_party_merch_code
     </sql>
 
     <select id="queryObject" resultMap="goodsMap">
@@ -94,8 +98,9 @@
         psr1.store_id,
         psr1.market_price,
         psr1.stock_num,
-        a.goods_desc,a.goods_biz_type,a.goods_rate
+        a.goods_desc,a.goods_biz_type,a.goods_rate,a.third_party_merch_code,mb.is_stock_share isStockShare
         from mall_goods a LEFT JOIN mall_product_store_rela psr1 ON a.id = psr1.goods_id and a.merch_sn = psr1.merch_sn
+        left join third_merchant_biz mb on a.third_party_merch_code = mb.third_party_merch_code and mb.merch_sn=a.merch_sn
 		where a.id = #{value}
 	</select>
 
@@ -122,7 +127,7 @@
         a.primary_pic_url,
         a.list_pic_url,
         psr1.retail_price,
-        a.sell_volume,
+        psr1.sell_volume,
         a.primary_product_id,
         a.unit_price,
         a.promotion_desc,
@@ -136,8 +141,9 @@
         psr1.store_id,
         psr1.market_price,
         psr1.stock_num,
-        a.goods_desc,a.goods_biz_type,a.goods_rate
+        a.goods_desc,a.goods_biz_type,a.goods_rate,a.third_party_merch_code,mb.is_stock_share isStockShare,a.sell_volume goods_sell_volume
         from mall_goods a left join mall_merch m on a.merch_sn = m.merch_sn
+        left join third_merchant_biz mb on a.third_party_merch_code = mb.third_party_merch_code and mb.merch_sn=a.merch_sn
         LEFT JOIN mall_product_store_rela psr1 ON a.id = psr1.goods_id and a.merch_sn = psr1.merch_sn
         where a.id = #{id} and psr1.store_id = #{storeId}
     </select>
@@ -150,12 +156,15 @@
         <if test="fields == null or fields == ''">
             a.*
         </if>
-        ,psr1.stock_num,psr1.category_id,psr1.brand_id,psr1.attribute_category
+        ,psr1.stock_num,psr1.category_id,psr1.brand_id,psr1.attribute_category,a.third_party_merch_code
+        ,a.goods_biz_type,a.goods_number,mb.is_stock_share isStockShare
         from mall_goods a
         LEFT JOIN mall_product_store_rela psr1 ON a.id = psr1.goods_id and a.merch_sn = psr1.merch_sn
+        left join third_merchant_biz mb on a.third_party_merch_code = mb.third_party_merch_code and mb.merch_sn=a.merch_sn
         LEFT JOIN mall_product b ON b.id = psr1.product_id
         left join mall_category c on psr1.category_id = c.id
-        where 1 = 1 and a.is_delete != 1 and psr1.stock_num > 0 and a.is_on_sale = 1
+        where 1 = 1
+        and a.is_delete != 1  and a.is_on_sale = 1
         <if test="is_new != null and is_new != ''">
             and a.is_new = #{is_new}
         </if>
@@ -220,10 +229,22 @@
         <if test="fields == null or fields == ''">
             a.*,b.id as product_id,psr1.category_id,psr1.brand_id,psr1.attribute_category
         </if>
+        ,a.goods_biz_type,
+        a.goods_number,
+        a.third_party_merch_code third_party_merch_code,
+        mb.is_stock_share isStockShare
         from mall_goods a
         LEFT JOIN mall_product_store_rela psr1 ON a.id = psr1.goods_id and a.merch_sn = psr1.merch_sn
+        left join third_merchant_biz mb on mb.third_party_merch_code = a.third_party_merch_code and mb.merch_sn=a.merch_sn
         LEFT JOIN mall_product b ON b.id = psr1.product_id
-        where 1 = 1 and b.id is not null and psr1.stock_num > 0 and a.is_delete != 1 and psr1.retail_price is not null and a.is_on_sale = 1
+        where 1 = 1
+        <if test="isStockShare == 1">
+            and (a.goods_number > 0  or psr1.stock_num > 0 )
+        </if>
+        <if test="isStockShare == 0">
+            and psr1.stock_num > 0
+        </if>
+        and b.id is not null and a.is_delete != 1 and psr1.retail_price is not null and a.is_on_sale = 1
         <if test="is_new != null and is_new != ''">
             and a.is_new = #{is_new}
         </if>
@@ -271,19 +292,22 @@
     </select>
 
     <select id="queryCatalogProductList" resultMap="goodsMap">
-        select a.id, a.name, a.list_pic_url,psr1.category_id,psr1.brand_id,psr1.attribute_category , psr1.market_price, psr1.retail_price, a.goods_brief, b.id AS product_id,psr1.stock_num
+        select a.id, a.name, a.list_pic_url,psr1.category_id,psr1.brand_id,psr1.attribute_category , psr1.market_price, psr1.retail_price, a.goods_brief, b.id AS product_id,
+        psr1.stock_num,a.third_party_merch_code,a.goods_biz_type,a.goods_number,
+        mb.is_stock_share isStockShare
         <if test="is_group != null and is_group == true">
            ,gg.id as group_id
         </if>
         FROM
         mall_goods a
         LEFT JOIN mall_product_store_rela psr1 ON a.id = psr1.goods_id and a.merch_sn = psr1.merch_sn
+        left join third_merchant_biz mb on a.third_party_merch_code = mb.third_party_merch_code and mb.merch_sn=a.merch_sn
         LEFT JOIN mall_product b ON b.id = psr1.product_id
         <if test="is_group != null and is_group == true">
             left join mall_goods_group gg on gg.goods_id = a.id
         </if>
         WHERE
-        1 = 1 AND psr1.stock_num > 0 and b.id > 0 and a.is_delete != 1 and psr1.retail_price is not null and a.is_on_sale = 1
+        1 = 1  and b.id > 0 and a.is_delete != 1 and psr1.retail_price is not null and a.is_on_sale = 1
         <if test="is_new != null and is_new != ''">
             and a.is_new = #{is_new}
         </if>
@@ -346,7 +370,14 @@
         select count(*)
         from mall_goods a
         left join mall_product_store_rela s on a.id = s.goods_id and a.merch_sn = s.merch_sn
-        where 1 = 1 and a.is_on_sale = 1 AND s.stock_num > 0
+        left join third_merchant_biz mb on a.third_party_merch_code = mb.third_party_merch_code and mb.merch_sn=a.merch_sn
+        where 1 = 1 and a.is_on_sale = 1
+        <if test="isStockShare == 1">
+          and (a.goods_number > 0  or s.stock_num > 0 )
+        </if>
+        <if test="isStockShare == 0">
+            and s.stock_num > 0
+        </if>
         <if test="storeId != null and storeId != ''">
             and s.store_id = #{storeId}
         </if>
@@ -393,4 +424,13 @@
             and a.goods_biz_type in ('00','11')
         </if>
     </select>
+
+    <update id="updateGoodsStock" parameterType="com.kmall.api.entity.GoodsVo">
+        update mall_goods a
+        <set>
+            <if test="goods_number != null">a.`goods_number` = #{goods_number},</if>
+            <if test="sell_volume != null">a.`sell_volume` = #{sell_volume},</if>
+        </set>
+        where a.id = #{id}
+    </update>
 </mapper>

+ 5 - 3
kmall-api/src/main/resources/mybatis/mapper/ApiProductMapper.xml

@@ -95,8 +95,9 @@
         FROM
         mall_product a
         LEFT JOIN mall_product_store_rela b ON a.id = b.product_id
+        left join mall_goods g on g.id=b.goods_id
         <where>
-            b.stock_num > 0
+            1=1 and (g.goods_number > 0  or b.stock_num > 0 )
             <if test="goods_id != null">
                 and a.goods_id = #{goods_id}
             </if>
@@ -122,8 +123,9 @@
         FROM
         mall_product a
         LEFT JOIN mall_product_store_rela b ON a.id = b.product_id
+        left join mall_goods g on g.id=b.goods_id
         <where>
-            b.stock_num > 0
+            1=1 and (g.goods_number > 0  or b.stock_num > 0 )
             <if test="goods_id != null">
                 and a.goods_id = #{goods_id}
             </if>
@@ -139,7 +141,7 @@
             <if test="stock_num != null">a.`stock_num` = #{stock_num},</if>
             <if test="sell_volume != null">a.`sell_volume` = #{sell_volume},</if>
         </set>
-        where a.product_id = #{id} and a.store_id = #{store_id}
+        where a.product_id = #{id} and a.store_id = #{store_id} and a.goods_id = #{goods_id}
     </update>
 
     <update id="updateSellVolumeNum" parameterType="com.kmall.api.entity.ProductVo">

+ 183 - 0
kmall-api/src/main/resources/mybatis/mapper/ApiThirdMerchantBizMapper.xml

@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.kmall.api.dao.ApiThirdMerchantBizMapper">
+
+    <resultMap type="com.kmall.api.entity.ThirdMerchantBizVo" id="thirdMerchantBizMap">
+        <result property="thirdMerchSn" column="third_merch_sn"/>
+		<result property="merchSn" column="merch_sn"/>
+        <result property="thirdPartyMerchCode" column="third_party_merch_code"/>
+        <result property="thirdPartyMerchName" column="third_party_merch_name"/>
+		<result property="isStockShare" column="is_stock_share"/>
+		<result property="isStoreUserShare" column="is_store_user_share"/>
+        <result property="isValid" column="is_valid"/>
+        <result property="createrSn" column="creater_sn"/>
+        <result property="createTime" column="create_time"/>
+        <result property="moderSn" column="moder_sn"/>
+        <result property="modTime" column="mod_time"/>
+        <result property="tstm" column="tstm"/>
+    </resultMap>
+
+	<select id="queryObject" resultType="com.kmall.api.entity.ThirdMerchantBizVo">
+		select
+			`third_merch_sn`,
+            `merch_sn`,
+			`third_party_merch_code`,
+			`third_party_merch_name`,
+			`is_valid`,
+			is_stock_share,
+			is_store_user_share,
+			`creater_sn`,
+			`create_time`,
+			`moder_sn`,
+			`mod_time`,
+			`tstm`
+		from third_merchant_biz
+		where third_merch_sn = #{id}
+	</select>
+
+	<select id="findByMerchSn" resultType="com.kmall.api.entity.ThirdMerchantBizVo">
+		select
+		`third_merch_sn`,
+		`merch_sn`,
+		`third_party_merch_code`,
+		`third_party_merch_name`,
+		`is_valid`,
+		is_stock_share,
+		is_store_user_share,
+		`creater_sn`,
+		`create_time`,
+		`moder_sn`,
+		`mod_time`,
+		`tstm`
+		from third_merchant_biz
+		where merch_sn = #{value}
+	</select>
+
+	<select id="getThirdMerchangByCode" resultType="com.kmall.api.entity.ThirdMerchantBizVo">
+		select
+		`third_merch_sn`,
+		`merch_sn`,
+		`third_party_merch_code`,
+		`third_party_merch_name`,
+		`is_valid`,
+		is_stock_share,
+		is_store_user_share,
+		`creater_sn`,
+		`create_time`,
+		`moder_sn`,
+		`mod_time`,
+		`tstm`
+		from third_merchant_biz
+		where third_party_merch_code = #{thirdMerchantCode}
+	</select>
+
+	<select id="queryList" resultType="com.kmall.api.entity.ThirdMerchantBizVo">
+		select
+    		`third_merch_sn`,
+			`merch_sn`,
+    		`third_party_merch_code`,
+    		`third_party_merch_name`,
+    		`is_valid`,
+			is_stock_share,
+		is_store_user_share,
+    		`creater_sn`,
+    		`create_time`,
+    		`moder_sn`,
+    		`mod_time`,
+    		`tstm`
+		from third_merchant_biz
+		WHERE 1=1
+		<if test="name != null and name.trim() != ''">
+			AND name LIKE concat('%',#{name},'%')
+		</if>
+		<if test="merchSn != null and merchSn.trim() != ''">
+			and merch_sn = #{merchSn}
+		</if>
+		<if test="thirdPartyMerchCode != null and thirdPartyMerchCode.trim() != ''">
+			and third_party_merch_code = #{thirdPartyMerchCode}
+		</if>
+        <choose>
+            <when test="sidx != null and sidx.trim() != ''">
+                order by ${sidx} ${order}
+            </when>
+			<otherwise>
+                order by third_merch_sn desc
+			</otherwise>
+        </choose>
+		<if test="offset != null and limit != null">
+			limit #{offset}, #{limit}
+		</if>
+	</select>
+	
+ 	<select id="queryTotal" resultType="int">
+		select count(*) from third_merchant_biz
+		WHERE 1=1
+        <if test="name != null and name.trim() != ''">
+            AND name LIKE concat('%',#{name},'%')
+        </if>
+		<if test="merchSn != null and merchSn.trim() != ''">
+			and merch_sn = #{merchSn}
+		</if>
+		<if test="thirdPartyMerchCode != null and thirdPartyMerchCode.trim() != ''">
+			and third_party_merch_code = #{thirdPartyMerchCode}
+		</if>
+	</select>
+
+	<insert id="save" parameterType="com.kmall.api.entity.ThirdMerchantBizVo" useGeneratedKeys="true" keyProperty="thirdMerchSn">
+		insert into third_merchant_biz(
+			`merch_sn`,
+			`third_party_merch_code`,
+			`third_party_merch_name`,
+			`is_valid`,
+			is_stock_share,
+			is_store_user_share,
+			`creater_sn`,
+			`create_time`,
+			`moder_sn`,
+			`mod_time`,
+			`tstm`)
+		values(
+			#{merchSn},
+			#{thirdPartyMerchCode},
+			#{thirdPartyMerchName},
+			#{isValid},
+			#{isStockShare},
+			#{isStoreUserShare},
+			#{createrSn},
+			#{createTime},
+			#{moderSn},
+			#{modTime},
+			#{tstm})
+	</insert>
+
+	<update id="update" parameterType="com.kmall.api.entity.ThirdMerchantBizVo">
+		update third_merchant_biz 
+		<set>
+			<if test="merchSn != null">`merch_sn` = #{merchSn},</if>
+			<if test="thirdPartyMerchCode != null">`third_party_merch_code` = #{thirdPartyMerchCode}, </if>
+			<if test="thirdPartyMerchName != null">`third_party_merch_name` = #{thirdPartyMerchName}, </if>
+			<if test="isValid != null">`is_valid` = #{isValid}, </if>
+			<if test="isStockShare != null">`is_stock_share` = #{isStockShare}, </if>
+			<if test="isStoreUserShare != null">`is_store_user_share` = #{isStoreUserShare}, </if>
+			<if test="createrSn != null">`creater_sn` = #{createrSn}, </if>
+			<if test="createTime != null">`create_time` = #{createTime}, </if>
+			<if test="moderSn != null">`moder_sn` = #{moderSn}, </if>
+			<if test="modTime != null">`mod_time` = #{modTime}, </if>
+			<if test="tstm != null">`tstm` = #{tstm}</if>
+		</set>
+		where third_merch_sn = #{thirdMerchSn}
+	</update>
+	
+	<delete id="delete">
+		delete from third_merchant_biz where third_merch_sn = #{value}
+	</delete>
+	
+	<delete id="deleteBatch">
+		delete from third_merchant_biz where third_merch_sn in 
+		<foreach item="thirdMerchSn" collection="array" open="(" separator="," close=")">
+			#{thirdMerchSn}
+		</foreach>
+	</delete>
+
+</mapper>

+ 11 - 0
kmall-common/pom.xml

@@ -80,6 +80,17 @@
             <artifactId>jstl</artifactId>
             <version>1.2</version>
         </dependency>
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz</artifactId>
+            <version>2.2.3</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>c3p0</artifactId>
+                    <groupId>c3p0</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
 
         <!-- POI依赖 ,处理EXCEL WORD  PDF�?-->
         <dependency>

+ 32 - 0
kmall-common/src/main/java/com/kmall/common/constant/Dict.java

@@ -916,4 +916,36 @@ public class Dict {
             this.itemName = itemName;
         }
     }
+
+    /**
+     * 商品库存是否共享 0:否 1:是
+     */
+    public enum isStockShare {
+        item_0("0", "否"),
+        item_1("1", "是");
+
+        private String item;
+        private String itemName;
+
+        isStockShare(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
 }

+ 45 - 0
kmall-common/src/main/java/com/kmall/common/listener/ContextFinalizer.java

@@ -0,0 +1,45 @@
+package com.kmall.common.listener;
+
+
+import com.alibaba.druid.proxy.DruidDriver;
+
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Enumeration;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+
+/**
+ * @author huangyq
+ * @version 1.0
+ * 2019-02-28 15:00
+ */
+
+@WebListener
+public class ContextFinalizer implements ServletContextListener {
+    @Override
+    public void contextDestroyed(ServletContextEvent sce) {
+        Enumeration<Driver> drivers = DriverManager.getDrivers();
+        Driver d = null;
+        while (drivers.hasMoreElements()) {
+            try {
+                d = drivers.nextElement();
+                DriverManager.deregisterDriver(d);
+                System.out.println(String.format("ContextFinalizer:Driver %s deregistered", d));
+            } catch (SQLException ex) {
+                System.out.println(String.format("ContextFinalizer:Error deregistering driver %s", d) + ":" + ex);
+            }
+        }
+//        try {
+//            DruidDriver.getInstance().resetStat().shutdown();
+//        } catch (InterruptedException e) {
+//            System.out.println("ContextFinalizer:SEVERE problem cleaning up: " + e.getMessage());
+//            e.printStackTrace();
+//        }
+    }
+    @Override
+    public void contextInitialized(ServletContextEvent sce) {
+    }
+}

+ 45 - 0
kmall-common/src/main/java/com/kmall/common/listener/QuartzContextListener.java

@@ -0,0 +1,45 @@
+package com.kmall.common.listener;
+
+import org.springframework.web.context.WebApplicationContext;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+/**
+ * @author huangyq
+ * @version 1.0
+ * 2019-02-28 15:10
+ */
+public class QuartzContextListener implements ServletContextListener {
+
+    @Override
+    public void contextDestroyed(ServletContextEvent arg0) {
+        WebApplicationContext webApplicationContext = (WebApplicationContext) arg0
+                .getServletContext()
+                .getAttribute(
+                        WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
+        org.quartz.impl.StdScheduler startQuertz = (org.quartz.impl.StdScheduler) webApplicationContext
+                .getBean("scheduler");
+        if(startQuertz != null) {
+            startQuertz.shutdown();
+        }
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * javax.servlet.ServletContextListener#contextInitialized(javax.servlet
+     * .ServletContextEvent)
+     */
+    @Override
+    public void contextInitialized(ServletContextEvent arg0) {
+
+    }
+
+}

+ 8 - 6
kmall-framework/src/main/webapp/WEB-INF/web.xml

@@ -23,12 +23,6 @@
             classpath*:kmall-*.xml
         </param-value>
     </context-param>
-
-    <!--<context-param>
-        <param-name>log4jRefreshInterval</param-name>
-        <param-value>600000</param-value>
-    </context-param>-->
-
     <!--logback 日志-->
     <context-param>
         <param-name>logbackConfigLocation</param-name>
@@ -45,6 +39,14 @@
     </listener>
 
     <listener>
+        <listener-class>com.kmall.common.listener.QuartzContextListener</listener-class>
+    </listener>
+
+    <listener>
+        <listener-class>com.kmall.common.listener.ContextFinalizer</listener-class>
+    </listener>
+
+    <listener>
         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
     </listener>
 

+ 8 - 0
kmall-framework/src/test/resources/applicationContext-test.xml

@@ -111,6 +111,14 @@
             </list>
         </property>
         <property name="connectionInitSqls" value="set names utf8mb4;"/>
+        <!--&lt;!&ndash; 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 &ndash;&gt;-->
+        <property name="timeBetweenEvictionRunsMillis" value="60000" />
+        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
+        <property name="minEvictableIdleTimeMillis" value="300000" />
+        <!-- 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效 -->
+        <property name="testWhileIdle" value="true" />
+        <!-- 指定每个连接上PSCache的大小   -->
+        <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
     </bean>
 
     <bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">

+ 2 - 0
kmall-schedule/src/main/java/com/kmall/schedule/dao/QzOrderMapper.java

@@ -34,6 +34,8 @@ public interface QzOrderMapper {
 
     void updateStockNum(Map param);
 
+    void updateGoodsStockNum(Map param);
+
     List<Map> queryRefundOrderList();
 
     void updateOrderRefund(Map param);

+ 38 - 32
kmall-schedule/src/main/java/com/kmall/schedule/service/QzOrderService.java

@@ -215,17 +215,43 @@ public class QzOrderService {
         List<Map> pastOrderList = qzOrderMapper.queryPastOrderList();
         if (null != pastOrderList && pastOrderList.size() > 0) {
             for (Map map : pastOrderList) {
-                Integer number = MapUtils.getInteger("number", map);
-                Integer stock_num = MapUtils.getInteger("stock_num", map);
-                Long storeRelaId = MapUtils.getLong("storeRelaId", map);
+                restStockNum(map);
+            }
+            qzOrderMapper.unpayPastUpdate();
+        }
+        logger.info(">>>>>>>>>>>>>>>>>>>>unpayPastUpdate is end ");
+    }
+
+    /**
+     * 还原库存
+     * @param map
+     */
+    private void restStockNum(Map map){
+        Integer number = MapUtils.getInteger("number", map);
+        Integer stock_num = MapUtils.getInteger("stock_num", map);
+        Long storeRelaId = MapUtils.getLong("storeRelaId", map);
+        String isStockShare = MapUtils.getString("is_stock_share", map);
+        Integer goods_number = MapUtils.getInteger("goods_number", map);
+        Long goods_id = MapUtils.getLong("goods_id", map);
+        String goods_biz_type = MapUtils.getString("goods_biz_type", map);
+        if(goods_biz_type.equalsIgnoreCase(Dict.orderBizType.item_00.getItem())){
+            if(goods_biz_type.equalsIgnoreCase(Dict.orderBizType.item_00.getItem()) && isStockShare.equalsIgnoreCase(Dict.isStockShare.item_1.getItem())) {//共享
+                Map param = Maps.newHashMap();
+                param.put("id", goods_id);
+                param.put("goods_number", goods_number + number);
+                qzOrderMapper.updateGoodsStockNum(param);//商户商品库存还原
+            }else{
                 Map param = Maps.newHashMap();
                 param.put("id", storeRelaId);
                 param.put("stock_num", stock_num + number);
-                qzOrderMapper.updateStockNum(param);
+                qzOrderMapper.updateStockNum(param);//门店库存还原
             }
-            qzOrderMapper.unpayPastUpdate();
+        }else{
+            Map param = Maps.newHashMap();
+            param.put("id", storeRelaId);
+            param.put("stock_num", stock_num + number);
+            qzOrderMapper.updateStockNum(param);//门店库存还原
         }
-        logger.info(">>>>>>>>>>>>>>>>>>>>unpayPastUpdate is end ");
     }
 
     /**
@@ -616,9 +642,7 @@ public class QzOrderService {
         String orderId = MapUtils.getString("order_id", map);
         String orderSn = MapUtils.getString("order_sn", map);
         String add_time = MapUtils.getString("add_time", map);
-        Integer number = MapUtils.getInteger("number", map);
-        Integer stock_num = MapUtils.getInteger("stock_num", map);
-        Long storeRelaId = MapUtils.getLong("storeRelaId", map);
+
         Date addTime = DateUtils.strToDate(add_time);
         Date nowDate = new Date();
 
@@ -642,10 +666,7 @@ public class QzOrderService {
                 } else if (result.getTrade_state().equalsIgnoreCase(Dict.tradeState.item_NOTPAY.getItem())) {//订单未支付
                     Map orderRaram = Maps.newHashMap();
                     if (getDateBetween(addTime, nowDate) >= 15) {//订单下单时间超过15分钟直接取消订单
-                        Map param = Maps.newHashMap();
-                        param.put("id", storeRelaId);
-                        param.put("stock_num", stock_num + number);
-                        qzOrderMapper.updateStockNum(param);//库存还原
+                        restStockNum(map);//库存还原
                         orderRaram.put("orderStatus", Dict.orderStatus.item_101.getItem());//订单状态已取消
                         orderRaram.put("payStatus", Dict.payStatus.item_0.getItem());//支付状态未支付
                     } else {
@@ -660,10 +681,7 @@ public class QzOrderService {
                     orderRaram.put("orderStatus", Dict.orderStatus.item_500.getItem());
                     orderRaram.put("orderId", orderId);
                     qzOrderMapper.updateOrderInfo(orderRaram);
-                    Map param = Maps.newHashMap();
-                    param.put("id", storeRelaId);
-                    param.put("stock_num", stock_num + number);
-                    qzOrderMapper.updateStockNum(param);//库存还原
+                    restStockNum(map);//库存还原
                     logger.info(">>>>>>>>>>>>>>>>>>>>wxOrderByTransactionIdQueryUpdFail 根据支付单查询微信接口返回信息:state 【" + result.getTrade_state() +
                             "】,des【" + result.getTrade_state_desc() + "】");
                 } else if (result.getTrade_state().equalsIgnoreCase(Dict.tradeState.item_PAYERROR.getItem())) {
@@ -736,10 +754,7 @@ public class QzOrderService {
                 } else if (result.getTrade_state().equalsIgnoreCase(Dict.tradeState.item_NOTPAY.getItem())) {//订单未支付
                     Map orderRaram = Maps.newHashMap();
                     if (getDateBetween(addTime, nowDate) >= 15) {//订单下单时间超过15分钟直接取消订单
-                        Map param = Maps.newHashMap();
-                        param.put("id", storeRelaId);
-                        param.put("stock_num", stock_num + number);
-                        qzOrderMapper.updateStockNum(param);//库存还原
+                        restStockNum(map);//库存还原
                         orderRaram.put("orderStatus", Dict.orderStatus.item_101.getItem());//订单状态已取消
                         orderRaram.put("payStatus", Dict.payStatus.item_0.getItem());//支付状态未支付
                     } else {
@@ -754,10 +769,7 @@ public class QzOrderService {
                     orderRaram.put("orderStatus", Dict.orderStatus.item_500.getItem());
                     orderRaram.put("orderId", orderId);
                     qzOrderMapper.updateOrderInfo(orderRaram);
-                    Map param = Maps.newHashMap();
-                    param.put("id", storeRelaId);
-                    param.put("stock_num", stock_num + number);
-                    qzOrderMapper.updateStockNum(param);//库存还原
+                    restStockNum(map);//库存还原
                     logger.info(">>>>>>>>>>>>>>>>>>>>wxGlobalOrderByTransactionIdQueryUpdFail 根据支付单查询微信国际接口返回信息:state 【" + result.getTrade_state() +
                             "】,des【" + Dict.tradeState.item_CLOSED.getItemName() + "】");
                 } else if (result.getTrade_state().equalsIgnoreCase(Dict.tradeState.item_PAYERROR.getItem())) {
@@ -804,9 +816,6 @@ public class QzOrderService {
                 String orderId = MapUtils.getString("order_id", map);
                 String orderSn = MapUtils.getString("order_sn", map);
                 String add_time = MapUtils.getString("add_time", map);
-                Integer number = MapUtils.getInteger("number", map);
-                Integer stockNum = MapUtils.getInteger("stock_num", map);
-                Long storeRelaId = MapUtils.getLong("storeRelaId", map);
 
                 PinganResponseDto response = PinganUtil.pinganPaystatus(outNo);
 
@@ -839,10 +848,7 @@ public class QzOrderService {
                             if (getDateBetween(addTime, nowDate) >= 15) {//订单下单时间超过15分钟直接取消订单
                                 orderRaram.put("payStatus", 0);//支付状态未支付
                                 orderRaram.put("orderStatus", 101);//订单状态已取消
-                                Map param = Maps.newHashMap();
-                                param.put("id", storeRelaId);
-                                param.put("stock_num", stockNum + number);
-                                qzOrderMapper.updateStockNum(param);
+                                restStockNum(map);//库存还原
                             } else {
                                 orderRaram.put("payStatus", 0);//支付状态未支付
                                 orderRaram.put("orderStatus", 0);//订单状态未支付

+ 3 - 0
kmall-schedule/src/main/resources/kmall-scheduler.xml

@@ -35,6 +35,9 @@
                 <prop key="org.quartz.jobStore.misfireThreshold">12000</prop>
                 <!-- 表前缀 -->
                 <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
+                <prop key="org.quartz.plugin.shutdownhook.class">org.quartz.plugins.management.ShutdownHookPlugin</prop>
+                <prop key="org.quartz.plugin.shutdownhook.cleanShutdown">true</prop>
+                <prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop>
             </props>
         </property>
 

+ 24 - 8
kmall-schedule/src/main/resources/mybatis/mapper/QzOrderMapper.xml

@@ -21,15 +21,18 @@
     </select>
 
     <select id="queryPastOrderList" resultType="map">
-        SELECT b.product_id,b.number,c.stock_num,c.id as storeRelaId
+        SELECT b.product_id,b.number,c.stock_num,c.id as storeRelaId,mb.is_stock_share,mb.third_party_merch_code,g.goods_number,g.id goods_id,g.goods_biz_type
         FROM mall_order a
         LEFT JOIN mall_order_goods b ON a.id = b.order_id
-        LEFT JOIN mall_product_store_rela c ON b.product_id = c.product_id
+        LEFT JOIN mall_product_store_rela c ON b.goods_id = c.goods_id
         AND c.store_id = a.store_id
+				left join mall_goods g on g.id=c.goods_id and g.merch_sn=c.merch_sn
+        left join third_merchant_biz mb on mb.third_party_merch_code=g.third_party_merch_code and mb.merch_sn=g.merch_sn
         WHERE 1 = 1
         AND a.add_time <![CDATA[ < ]]> DATE_ADD(now(),INTERVAL -15 MINUTE)
         AND a.order_status in (0,100) and a.order_type = 1 AND a.is_onffline_order = 0
     </select>
+
     <update id="unpayPastUpdate">
         UPDATE mall_order a
         SET order_status=101,shipping_status=0,pay_status=0
@@ -45,6 +48,13 @@
         </set>
         where a.id = #{id}
     </update>
+    <update id="updateGoodsStockNum" parameterType="map">
+        update mall_goods a
+        <set>
+            <if test="stock_num != null">a.`goods_number` = #{goods_number},</if>
+        </set>
+        where a.id = #{id}
+    </update>
 
 
     <select id="queryRefundOrderList" resultType="map">
@@ -58,22 +68,28 @@
 
     <select id="queryPayingOrderList" resultType="map">
 		select a.pay_transaction_id,a.order_sn,a.order_status,a.pay_status,a.id 'order_id',a.merch_order_sn,date_format(a.add_time,'%Y-%m-%d %H:%i:%s') as add_time,
-        b.product_id,b.number,c.stock_num,c.id as storeRelaId,a.pay_flag
+        b.product_id,b.number,c.stock_num,c.id as storeRelaId,a.pay_flag,mb.is_stock_share,mb.third_party_merch_code,g.goods_number,g.id goods_id,g.goods_biz_type
         from mall_order a
         LEFT JOIN mall_order_goods b ON a.id = b.order_id
-        LEFT JOIN mall_product_store_rela c ON b.product_id = c.product_id
-        AND c.store_id = a.store_id  where (a.order_status in ('0','100','201') and a.pay_status in (0,1,2)) and pay_id is not null
+        LEFT JOIN mall_product_store_rela c ON b.goods_id = c.goods_id
+        AND c.store_id = a.store_id
+		left join mall_goods g on g.id=c.goods_id and g.merch_sn=c.merch_sn
+        left join third_merchant_biz mb on mb.third_party_merch_code=g.third_party_merch_code and mb.merch_sn=g.merch_sn
+		where (a.order_status in ('0','100','201') and a.pay_status in (0,1,2)) and pay_id is not null
         and (a.pay_transaction_id = '' or a.pay_transaction_id is null or a.pay_time is null or a.pay_time = '')
         AND a.is_onffline_order = 0 and a.pay_flag = 'weixin'
     </select>
 
     <select id="queryPinganPayingOrderList" resultType="map">
 		select a.pay_transaction_id,a.order_sn,a.order_status,a.pay_status,a.id 'order_id',a.merch_order_sn,date_format(a.add_time,'%Y-%m-%d %H:%i:%s') as add_time,
-        b.product_id,b.number,c.stock_num,c.id as storeRelaId,a.pay_flag
+        b.product_id,b.number,c.stock_num,c.id as storeRelaId,a.pay_flag,mb.is_stock_share,mb.third_party_merch_code,g.goods_number,g.id goods_id,g.goods_biz_type
         from mall_order a
         LEFT JOIN mall_order_goods b ON a.id = b.order_id
-        LEFT JOIN mall_product_store_rela c ON b.product_id = c.product_id
-        AND c.store_id = a.store_id  where (a.order_status in ('0','100','201') and a.pay_status in (0,1,2)) and pay_id is not null
+        LEFT JOIN mall_product_store_rela c ON b.goods_id = c.goods_id
+        AND c.store_id = a.store_id
+		left join mall_goods g on g.id=c.goods_id and g.merch_sn=c.merch_sn
+        left join third_merchant_biz mb on mb.third_party_merch_code=g.third_party_merch_code and mb.merch_sn=g.merch_sn
+        where (a.order_status in ('0','100','201') and a.pay_status in (0,1,2)) and pay_id is not null
         and (a.pay_transaction_id = '' or a.pay_transaction_id is null or a.pay_time is null or a.pay_time = '')
         AND a.is_onffline_order = 0 and a.pay_flag = 'pingan'
     </select>

+ 1 - 1
pom.xml

@@ -28,7 +28,7 @@
         <mybatis-spring-version>1.3.0</mybatis-spring-version>
         <mysql-version>5.1.39</mysql-version>
         <hibernate-validator-version>5.4.1.Final</hibernate-validator-version>
-        <druid-version>1.0.28</druid-version>
+        <druid-version>1.1.14</druid-version>
         <mariadb-version>2.0.2</mariadb-version>
         <HikariCP-version>2.6.3</HikariCP-version>
         <commons-lang-version>2.6</commons-lang-version>

+ 2 - 1
wx-mall/app.js

@@ -26,6 +26,7 @@ App({
       avatarUrl: 'http://120.76.26.84:80/group1/M00/00/01/rBJEdVvr17OACigOAAAB_us54MA744.png'
     },
     token: '',
-    appGoodsBizType: '00'
+    appGoodsBizType: '00',
+    appCheckCart: '00'
   }
 })

+ 1 - 1
wx-mall/app.wxss

@@ -208,7 +208,7 @@ view, text {
   border-radius: 40rpx;
   background-color: #4d4d4e;
   position: fixed;
-  bottom: 20rpx;
+  bottom: 8rpx;
   z-index: 499;
   left: 50%;
   margin-left: -350rpx;

+ 64 - 20
wx-mall/pages/cart/cart.js

@@ -36,9 +36,11 @@ Page({
     retailPrice: '',
     stockNum: 0,
     cartNumber: 0,
-    checkCart: '00',
+    checkCart: app.globalData.appCheckCart,
     total00: 0,
-    total11: 0
+    total11: 0,
+    page: 1,
+    size: 4
   },
   onLoad: function(options) {
     // 页面初始化 options为页面跳转所带来的参数
@@ -49,6 +51,9 @@ Page({
   },
   onShow: function () {
     let that = this;
+    that.setData({
+      checkCart: app.globalData.appCheckCart
+    });
     // 页面显示
     if (wx.getStorageSync('userInfo') || wx.getStorageSync('token')) {
       if (wx.getStorageSync('storeId')) {
@@ -62,6 +67,10 @@ Page({
             that.reLoad();
           }
         });
+        that.setData({
+          footprintList: [],
+          page: 1
+        });
         that.getCartList();
         that.getFootprintList();
       }else{
@@ -81,23 +90,32 @@ Page({
     switch (currentId) {
       case 'defaultActivity':
         that.setData({
-          'checkCart': '00'
+          'checkCart': '00',
+          footprintList: [],
+          page: 1
         });
+        app.globalData.appCheckCart = '00';
         this.getCartList();
         this.getFootprintList();
         break;
       case 'ordActivity':
         that.setData({
-          'checkCart': '11'
+          'checkCart': '11',
+          footprintList: [],
+          page: 1
         });
+        app.globalData.appCheckCart = '11';
         this.getCartList();
         this.getFootprintList();
         break;
       default:
         //综合排序
         that.setData({
-          'checkCart': '00'
+          'checkCart': '00',
+          footprintList: [],
+          page: 1
         });
+        app.globalData.appCheckCart = '00';
         this.getCartList();
         this.getFootprintList();
     }
@@ -484,19 +502,6 @@ Page({
       }
     });
   },
-  getFootprintList() {
-    let that = this;
-    util.request(api.GuessFootprintList, {
-      storeId: wx.getStorageSync('storeId'),
-      checkCart: that.data.checkCart
-    }, ).then(function(res) {
-      if (res.errno === 0) {
-        that.setData({
-          footprintList: res.data.list
-        });
-      }
-    });
-  },
   switchAttrPop: function() {
     this.setData({
       openAttr: !this.data.openAttr
@@ -552,12 +557,22 @@ Page({
       goodsId: goodsId
     }).then(function(res) {
       if (res.errno === 0 && null != res.data) {
+        let stockNumbers = 0;
+        if (res.data.goodsVo.goodsBizType=='00') {
+          if (res.data.goodsVo.isStockShare == 1) {
+            stockNumbers = res.data.goodsVo.goods_number;
+          } else {
+            stockNumbers = res.data.goodsVo.stockNum;
+          }
+        } else {
+          stockNumbers = res.data.goodsVo.stockNum;
+        }
         that.setData({
           goodsVo: res.data.goodsVo,
           specificationList: res.data.specificationList,
           productList: res.data.productList,
           openAttr: !that.data.openAttr,
-          stockNum: res.data.productList[0].stock_num,
+          stockNum: stockNumbers,
           cartNumber: res.data.cartNumber,
           checkedSpecText: res.data.specificationList[0].valueList[0].value
         });
@@ -612,7 +627,9 @@ Page({
           mask: true
         });
         that.setData({
-          openAttr: !that.data.openAttr
+          openAttr: !that.data.openAttr,
+          footprintList:[],
+          page:1
         })
         // 页面显示
         that.getCartList();
@@ -645,5 +662,32 @@ Page({
         }
       }
     });
+  },
+  getFootprintList() {
+    let that = this;
+    util.request(api.GuessFootprintList, {
+      storeId: wx.getStorageSync('storeId'),
+      checkCart: that.data.checkCart, page: that.data.page, size: that.data.size
+    }).then(function (res) {
+      if (res.errno === 0) {
+        let goodsList = that.data.footprintList.concat(res.data.list);
+        that.setData({
+          footprintList: goodsList
+        });
+        wx.hideLoading();
+      }
+    });
+  },
+  onReachBottom() {
+    var that = this;
+    if(!that.data.footprintList){
+      // wx.showLoading({
+      //   title: '加载中...',
+      // })
+    }
+    that.setData({
+      page: that.data.page + 1
+    });
+    that.getFootprintList();
   }
 })

+ 4 - 3
wx-mall/pages/cart/cart.wxml

@@ -16,7 +16,7 @@
     <!-- <view class="item">30分钟速达</view>
     <view class="item">每日优选生鲜</view>
     <view class="item">满88元免配送费</view> -->
-    <view class="item">新用户可领取5元优惠券</view>
+    <!-- <view class="item">新用户可领取5元优惠券</view> -->
   </view> 
   <view class="no-cart" wx:if="{{cartGoods.length <= 0}}" bindtap="hideSwitchAttrPop">
     <view class="c">
@@ -66,8 +66,8 @@
                   <view class="selnum">
                     <view class="cut" data-goods-id="{{item.id}}" data-item-index="{{index}}" data-product-id="{{item.product_id}}" bindtap="cutNumber"></view>
                     <input value="{{item.number}}" class="number" disabled="true" type="number" />
-                    
-                    <image class="add2" src="{{item.number < item.stockNum ? '/static/images/service-hsjh.png':'/static/images/service-ehsjh.png'}}" data-goods-id="{{item.id}}" data-item-index="{{index}}" data-product-id="{{item.product_id}}" catchtap="{{item.number < item.stockNum ?  'addNumber' : ''}}"></image>
+                    <image wx:if="{{item.isStockShare==1}}" class="add2" src="{{item.number < item.goodsNumber ? '/static/images/service-hsjh.png':'/static/images/service-ehsjh.png'}}" data-goods-id="{{item.id}}" data-item-index="{{index}}" data-product-id="{{item.product_id}}" catchtap="{{item.number < item.goodsNumber ?  'addNumber' : ''}}"></image>
+                    <image wx:if="{{item.isStockShare==0}}" class="add2" src="{{item.number < item.stockNum ? '/static/images/service-hsjh.png':'/static/images/service-ehsjh.png'}}" data-goods-id="{{item.id}}" data-item-index="{{index}}" data-product-id="{{item.product_id}}" catchtap="{{item.number < item.stockNum ?  'addNumber' : ''}}"></image>
                     
                   </view>
                 </view>
@@ -263,6 +263,7 @@
                   <view class="c">
                     <view class="p">价格:¥{{goodsVo.retail_price}}</view>
                     <view class="a" wx:if="{{productList.length>0}}">已选择:{{checkedSpecText}}</view>
+                    <view class="a">库存{{goodsVo.goodsBizType==00 && goodsVo.isStockShare==1?goodsVo.goods_number:goodsVo.stockNum}}件</view>
                   </view>
                 </view>
               </view>

+ 1 - 1
wx-mall/pages/cart/cart.wxss

@@ -531,7 +531,7 @@ page {
 }
 
 .attr-pop .info {
-  float: left;
+  /* float: left; */
   height: 177rpx;
   display: flex;
   align-items: flex-start;

+ 79 - 14
wx-mall/pages/catalog/catalog.js

@@ -22,12 +22,14 @@ Page({
     filterDiscount: 0,// 0不限 1特价 2活动
     goodsBizType: app.globalData.appGoodsBizType,//业务类型
     page: 1,
-    size: 50,
+    size: 4,
     showNavList: false,
     footCart: {},
     referrer: 0,
     sourceKey: '',
-    openCoupon: false
+    openCoupon: false,
+    refresh: false,
+    hidden: false
   },
   toggleNav() {
     this.setData({
@@ -59,6 +61,9 @@ Page({
     });
   },
   getCatalog: function () {
+    wx.showLoading({
+      title: '加载中...',
+    })
     //CatalogList
     let that = this;
     util.request(api.CatalogList).then(function (res) {
@@ -85,7 +90,11 @@ Page({
           });
         }
       }
-      that.getCategoryData();
+
+      if (that.data.goodsList.length == 0) {
+        that.getCategoryData();
+      }
+      wx.hideLoading();
     });
     util.request(api.GoodsCount).then(function (res) {
       that.setData({
@@ -99,7 +108,9 @@ Page({
       .then(function (res) {
         that.setData({
           currentCategory: res.data.currentCategory,
-          brandList: res.data.brandList
+          brandList: res.data.brandList,
+          goodsList: [],
+          page: 1
         });
         // console.log(res.data.brandList);
         that.getGoodsList();
@@ -194,12 +205,15 @@ Page({
   //
   getCategoryData: function () {
     let that = this;
+    that.setData({
+      goodsList: []
+    });
     that.getGoodsList();
   },
   getGoodsList() {
-    wx.showLoading({
-      title: '加载中...',
-    });
+    // wx.showLoading({
+    //   title: '加载中...',
+    // });
     var that = this;
     if (that.data.currentCategory){
       util.request(api.CatalogProductList, {
@@ -213,11 +227,17 @@ Page({
       })
         .then(function (res) {
           if (res.errno === 0) {
+            let goodsList = that.data.goodsList.concat(res.data.data);
             that.setData({
-              goodsList: res.data.data,
-              filterCategory: res.data.filterCategory
+              goodsList: goodsList,
+              filterCategory: res.data.filterCategory,
+              refresh: true
             });
-            wx.hideLoading();
+            if(that.data.page == 4){
+              that.setData({refresh: true});
+            }else{
+              that.setData({hidden: true })
+            }
           }
         });
     }
@@ -302,28 +322,36 @@ Page({
     switch (currentId) {
       case 'defaultActivity':
         that.setData({
-          'goodsBizType': '00'
+          'goodsBizType': '00',
+          goodsList: [],
+          page: 1
         });
         app.globalData.appGoodsBizType = '00';
         this.getGoodsList();
         break;
       case 'discountActivity':
         that.setData({
-          'goodsBizType': '02'
+          'goodsBizType': '02',
+          goodsList: [],
+          page: 1
         });
         app.globalData.appGoodsBizType = '02';
         this.getGoodsList();
         break;
       case 'groupActivity':
         that.setData({
-          'goodsBizType': '10'
+          'goodsBizType': '10',
+          goodsList: [],
+          page: 1
         });
         app.globalData.appGoodsBizType = '10';
         this.getGoodsList();
         break;
       case 'ordActivity':
         that.setData({
-          'goodsBizType': '11'
+          'goodsBizType': '11',
+          goodsList: [],
+          page: 1
         });
         app.globalData.appGoodsBizType = '11';
         this.getGoodsList();
@@ -336,6 +364,8 @@ Page({
         this.setData({
           'currentSortType': 'sell',
           'currentSortOrder': tmpSortOrder,
+          goodsList: [],
+          page: 1
         });
         this.getGoodsList();
         break;
@@ -347,6 +377,8 @@ Page({
         this.setData({
           'currentSortType': 'price',
           'currentSortOrder': tmpSortOrder,
+          goodsList: [],
+          page: 1
         });
 
         this.getGoodsList();
@@ -356,6 +388,8 @@ Page({
         this.setData({
           'currentSortType': 'default',
           'currentSortOrder': 'desc',
+          goodsList: [],
+          page: 1
         });
         this.getGoodsList();
     }
@@ -423,5 +457,36 @@ Page({
     wx.navigateTo({
       url: '/pages/categoryBrand/categoryBrand?brandId=' + replyType + '&&goodsBizType=' + that.data.goodsBizType + '&&currentIndex=' + currentIndex
     })
+  },
+  // onReachBottom() {
+  //   var that = this;
+  //   wx.showLoading({
+  //     title: '加载中...',
+  //   })
+  //   that.setData({
+  //     page: that.data.page + 1
+  //   });
+  //   if(that.data.page > that.data.total){
+  //     that.setData({
+  //       hidden: false
+  //     });
+  //   }
+  //   that.getGoodsList();
+  // },
+  onLoaderMoreMovies: function () {
+    var that = this;
+    wx.showNavigationBarLoading();
+    if (that.data.goodsList.length > 0) {
+      wx.showLoading({
+        title: '加载中...',
+      });
+      that.setData({
+        page: that.data.page + 1
+      });
+    }
+    console.log('加载');
+    that.getGoodsList();
+    wx.hideNavigationBarLoading()
   }
+
 })

+ 4 - 1
wx-mall/pages/catalog/catalog.json

@@ -1,3 +1,6 @@
 {
-  "navigationBarTitleText": "分类"
+  "navigationBarTitleText": "分类",
+  "enablePullDownRefresh": true,
+  "backgroundColor": "#f0145a",
+  "onReachBottomDistance": 50
 }

+ 27 - 24
wx-mall/pages/catalog/catalog.wxml

@@ -79,7 +79,7 @@
           </button>
       </view> -->
     </scroll-view>
-    <scroll-view class="cate" scroll-y="true">
+    <scroll-view class="cate" scroll-y="true" bindscrolltolower='onLoaderMoreMovies'>
       <navigator url="url" class="banner">
         <image class="image" wx:if="{{currentCategory.wap_banner_url}}" src="{{currentCategory.wap_banner_url}}"></image>
         <view class="txt">{{currentCategory.front_name?currentCategory.front_name:""}}</view>
@@ -123,48 +123,51 @@
       </view>
       <view class="cate-item">
         <view wx:if="{{goodsList != null && goodsList.length == 0}}" class="item-text">未找到相关商品</view>
+
+        <!-- 商品开始 -->
         <view class="item" wx:for="{{goodsList}}" wx:for-index="index" wx:for-item="item" wx:key="{{item.id}}">
           <navigator url="/pages/goods/goods?id={{item.id}}">
             <view class="left">
               <image class="img" wx:if="{{item.list_pic_url}}" src="{{item.list_pic_url}}"></image>
             </view>
           </navigator>
-
+          <!-- 文字开始 -->
           <view class="right">
             <view class="text">
-
-          <navigator url="/pages/goods/goods?id={{item.id}}">
-            <text class="name" bindtap="bindtapGoodsDetail" data-item-id="{{filterDiscount != 2?item.id:item.group_id}}">{{item.name?item.name:""}}</text>
-            <text class="desc" bindtap="bindtapGoodsDetail" data-item-id="{{filterDiscount != 2?item.id:item.group_id}}">{{item.goods_brief?item.goods_brief:""}}</text>
-          </navigator>
-
-
-          <view class="goods-do">
             <navigator url="/pages/goods/goods?id={{item.id}}">
-              <text class="price">{{item.retail_price?"¥"+item.retail_price:"¥0"}}</text>
-              <text class="org-price line-through">{{item.market_price?"¥"+item.market_price:""}}</text>
+              <text class="name" bindtap="bindtapGoodsDetail" data-item-id="{{filterDiscount != 2?item.id:item.group_id}}">{{item.name?item.name:""}}</text>
+              <text class="desc" bindtap="bindtapGoodsDetail" data-item-id="{{filterDiscount != 2?item.id:item.group_id}}">{{item.goods_brief?item.goods_brief:""}}</text>
             </navigator>
-            <!-- //数量加减 -->
-            <view class="number-item">
-                  <view class="selnum">
-                    <view class="cut" data-goods-id="{{item.id}}" data-product-id="{{item.product_id}}" bindtap="cutNumber"></view>
+
+            <!-- 描述开始 -->
+            <view class="goods-do">
+              <navigator url="/pages/goods/goods?id={{item.id}}">
+                <text class="price">{{item.retail_price?"¥"+item.retail_price:"¥0"}}</text>
+                <text class="org-price line-through">{{item.market_price?"¥"+item.market_price:""}}</text>
+              </navigator>
+              <!-- //数量加减 -->
+              <!-- <view class="number-item">
+                <view class="selnum">
+                  <view class="cut" data-goods-id="{{item.id}}" data-product-id="{{item.product_id}}" bindtap="cutNumber"></view>
                     <input value="{{item.cart_num}}" class="number" disabled="true" type="number" />
-                    <!-- <view class="add" data-goods-id="{{item.id}}" data-product-id="{{item.product_id}}" bindtap="addNumber"></view> -->
-                    <image class="add2" src="{{item.cart_num < item.stockNum ? '/static/images/service-hsjh.png':'/static/images/service-ehsjh.png'}}" data-goods-id="{{item.id}}" data-product-id="{{item.product_id}}"  catchtap="{{item.cart_num < item.stockNum ?  'addNumber' : ''}}"></image>
+                    <image wx:if="{{item.goodsBizType==11}}" class="add2" src="{{item.cart_num < item.stockNum ? '/static/images/service-hsjh.png':'/static/images/service-ehsjh.png'}}" data-goods-id="{{item.id}}" data-product-id="{{item.product_id}}"  catchtap="{{item.cart_num < item.stockNum ?  'addNumber' : ''}}"></image>
+                    <image wx:if="{{item.goodsBizType!=11}}" class="add2" src="{{item.cart_num < item.goods_number ? '/static/images/service-hsjh.png':'/static/images/service-ehsjh.png'}}" data-goods-id="{{item.id}}" data-product-id="{{item.product_id}}"  catchtap="{{item.cart_num < item.goods_number ?  'addNumber' : ''}}"></image>
                   </view>
-                </view>
+                </view> -->
               </view>
             </view>
-
+            <!-- 描述结束 -->
           </view>
-
+          <!-- 文字结束 -->
         </view>
+          <!-- 商品结束 -->
+        <view wx:if="{{hidden && goodsList != null && goodsList.length > 0}}" class="item-text">加载完成</view>
       </view>
     </scroll-view>
   </view>
 
   <view class="coupon" wx:if="{{openCoupon}}">
-     <view class="attr-close" bindtap="closeCoupon">X</view>
-      <image class="img" src="/static/imgys/coupon-gun.png" bindtap="takeShareCoupon"/>
-    </view>
+    <view class="attr-close" bindtap="closeCoupon">X</view>
+    <image class="img" src="/static/imgys/coupon-gun.png" bindtap="takeShareCoupon"/>
+  </view>
 </view>

+ 1 - 1
wx-mall/pages/catalog/catalog.wxss

@@ -252,7 +252,7 @@ page {
   overflow: hidden;
   border-top: 1rpx solid #f4f4f4;
   margin-top: 20rpx;
-  margin-bottom: 100rpx;
+  margin-bottom: 200rpx;
 }
 
 .cate-item .item {

+ 87 - 57
wx-mall/pages/category/category.js

@@ -16,14 +16,16 @@ Page({
     scrollTop: 0,
     scrollHeight: 0,
     page: 1,
-    size: 10,
+    size: 4,
     showNavList: false,
     footCart: {},
     openAttr: false,
     productList: {},
     specificationList: {},
     checkedSpecText: '请选择规格数量',
-    number: 1
+    number: 1,
+    stockNum: 0,
+    cartNumber: 0,
   },
   toggleNav() {
     this.setData({
@@ -158,17 +160,22 @@ Page({
           //显示错误信息
         }
       });
-    },
-    onReady: function () {
-        // 页面渲染完成
-    },
-    onShow: function () {
-        // 页面显示
-        this.getFootCart();
-    },
-    onHide: function () {
-        // 页面隐藏
-    },
+  },
+  onReady: function () {
+    // 页面渲染完成
+  },
+  onShow: function () {
+    // 页面显示
+    this.getFootCart();
+  },
+  onHide: function () {
+    // 页面隐藏
+  },
+  hideSwitchAttrPop: function () {
+    this.setData({
+      openAttr: false
+    })
+  },
   getGoodsList: function () {
     var that = this;
     wx.showLoading({
@@ -194,31 +201,46 @@ Page({
     ,
     //购物车增加
     addCart: function (e) {
-        let that = this;
-        var goodsId = e.currentTarget.dataset.goodsId;
-        util.request(api.GoodsSku, {goodsId: goodsId}).then(function (res) {
-            if (res.errno === 0 && null != res.data) {
-                that.setData({
-                    goodsVo: res.data.goodsVo,
-                    specificationList: res.data.specificationList,
-                    productList: res.data.productList,
-                    openAttr: !that.data.openAttr,
-                    checkedSpecText: res.data.specificationList[0].valueList[0].value
-                });
-                //
-                let _specificationList = res.data.specificationList;
-                for (let i = 0; i < _specificationList.length; i++) {
-                    if (_specificationList[i].valueList.length == 1) {
-                        //如果已经选中,则反选
-                        _specificationList[i].valueList[0].checked = true;
-                    }
-                }
-                that.setData({
-                    'specificationList': _specificationList
-                });
-
+      let that = this;
+      that.setData({
+        number: 1
+      });
+      var goodsId = e.currentTarget.dataset.goodsId;
+      util.request(api.GoodsSku, { goodsId: goodsId }).then(function (res) {
+        if (res.errno === 0 && null != res.data) {
+          let stockNumbers = 0;
+          if (res.data.goodsVo.goodsBizType == '00') {
+            if (res.data.goodsVo.isStockShare == 1) {
+              stockNumbers = res.data.goodsVo.goods_number;
+            } else {
+              stockNumbers = res.data.goodsVo.stockNum;
             }
-        });
+          } else {
+            stockNumbers = res.data.goodsVo.stockNum;
+          }
+          that.setData({
+            goodsVo: res.data.goodsVo,
+            specificationList: res.data.specificationList,
+            productList: res.data.productList,
+            stockNum: stockNumbers,
+            openAttr: !that.data.openAttr,
+            cartNumber: res.data.cartNumber,
+            checkedSpecText: res.data.specificationList[0].valueList[0].value
+          });
+          //
+          let _specificationList = res.data.specificationList;
+          for (let i = 0; i < _specificationList.length; i++) {
+            if (_specificationList[i].valueList.length == 1) {
+              //如果已经选中,则反选
+              _specificationList[i].valueList[0].checked = true;
+            }
+          }
+          that.setData({
+            'specificationList': _specificationList
+          });
+
+        }
+      });
     }
     ,
     clickSkuValue: function (event) {
@@ -280,26 +302,29 @@ Page({
         if (checkedProduct.stock_num < this.data.number) {
             //找不到对应的product信息,提示没有库存
             return false;
+      }
+      util.request(api.CartAdd, {
+        goodsId: goodsId,
+        productId: checkedProduct[0].id,
+        number: this.data.number
+      }, 'POST').then(function (res) {
+        if (res.errno === 0 && null != res.data) {
+          wx.showToast({
+            title: '添加成功',
+            icon: 'success',
+            mask: true
+          });
+          that.setData({
+            openAttr: !that.data.openAttr
+          })
+          that.getFootCart();
+        } else {
+          wx.showToast({
+            title: res.errmsg,
+            icon: 'none'
+          })
         }
-        util.request(api.CartAdd, {
-            goodsId: goodsId,
-            productId: checkedProduct[0].id,
-            number: this.data.number
-        }, 'POST').then(function (res) {
-            if (res.errno === 0 && null != res.data) {
-                wx.showToast({
-                    title: '添加成功',
-                    icon: 'success',
-                    mask: true
-                });
-                that.setData({
-                    openAttr: !that.data.openAttr
-                })
-                that.getFootCart();
-            } else {
-                util.showErrorToast(res.errmsg)
-            }
-        });
+      });
     },
   switchCate: function (event) {
     console.log(this.data.scrollLeft);
@@ -332,8 +357,13 @@ Page({
   },
   onReachBottom() {
     var that = this;
+    if (!that.data.goodsList) {
+      wx.showLoading({
+        title: '加载中...',
+      })
+    }
     that.setData({
-      page: that.data.page + 1,
+      page: that.data.page + 1
     });
     that.getGoodsList();
   }

+ 3 - 2
wx-mall/pages/category/category.json

@@ -1,4 +1,5 @@
 {
-  "onReachBottomDistance": 450,
-  "navigationBarTitleText": "分类"
+  "onReachBottomDistance": 50,
+  "navigationBarTitleText": "分类",
+  "enablePullDownRefresh": true
 }

+ 26 - 5
wx-mall/pages/category/category.wxml

@@ -1,5 +1,5 @@
 <view class="container">
-  <view class="cart-panel" wx:if="{{footCart.goodsCount>0}}">
+  <view class="cart-panel" wx:if="{{footCart.goodsCount>0}}" bindtap="hideSwitchAttrPop">
     <view class="cart-icon">
       <navigator class="nav-cell" open-type='switchTab' url="/pages/cart/cart">
         <image src="../../static/images/cart-fixed.png">
@@ -49,15 +49,34 @@
     </view>
     <view wx:if="{{showNavList}}" class="close" bindtap="toggleNav">X</view>
   </view>
-  <view class="cate-nav">
+  <view class="cate-nav" bindtap="hideSwitchAttrPop">
     <scroll-view scroll-x="true" class="cate-nav-body" style="width: 750rpx;" scroll-left="{{scrollLeft}}" >
       <view wx:for="{{navList}}" class="item {{ id == item.id ? 'active' : ''}}" data-current="{{index}}" data-id="{{item.id}}" bindtap="switchCate" wx:key="{{index}}">
         <view class="name">{{item.name}}</view>
       </view>
     </scroll-view>
   </view>
+  <scroll-view scroll-y="true" class="cate-item" bindtap="hideSwitchAttrPop">
+    <view class="h">
+      <text class="name">{{currentCategory.name}}</text>
+      <text class="desc">{{currentCategory.front_name?currentCategory.front_name:""}}</text>
+    </view>
+    <view class="b">
+      <block wx:for="{{goodsList}}" wx:for-index="iindex" wx:for-item="iitem" wx:key="unique">
+        <view class="item {{iindex % 2 == 0 ? 'item-b' : '' }}">
+         <navigator url="../goods/goods?id={{iitem.id}}&&currentIndex={{navIndex}}">
+            <image class="img" src="{{iitem.list_pic_url}}"></image>
+            <text class="name">{{iitem.name}}</text>
+          </navigator>
+          <view class="price">¥{{iitem.retail_price == null?'':iitem.retail_price}}
+            <image class="cart" src="/static/images/cart.png" data-goods-id="{{iitem.id}}" data-product-id="{{iitem.product_id}}" bindtap='addCart' background-size="cover"></image>
+          </view>
+        </view>
+      </block>
+    </view>
+  </scroll-view>
   <!-- bindchange="switchTab" -->
-  <swiper class="" current="{{currentTab}}" scroll-top="{{scrollTop}}" style="height:{{scrollHeight}}px;">
+  <!-- <swiper class="" current="{{currentTab}}" scroll-top="{{scrollTop}}" style="height:{{scrollHeight}}px;">
     <swiper-item wx:for="{{navList}}"  wx:key="{{navIndex}}">
       <scroll-view scroll-y="true" class="cate-item">
         <view class="h">
@@ -81,7 +100,7 @@
         </view>
       </scroll-view>
     </swiper-item>
-  </swiper>
+  </swiper> -->
 
    <view wx:if="{{openAttr}}" class="attr-pop">
           <view class="attr-close" bindtap="switchAttrPop">X</view>
@@ -91,6 +110,7 @@
               <view class="c">
                 <view class="p">价格:¥{{goodsVo.retail_price}}</view>
                 <view class="a" wx:if="{{productList.length>0}}">已选择:{{checkedSpecText}}</view>
+                <view class="a">库存{{goodsVo.goodsBizType==00 && goodsVo.isStockShare==1?goodsVo.goods_number:goodsVo.stockNum}}件</view>
               </view>
             </view>
           </view>
@@ -107,7 +127,8 @@
               <view class="selnum">
                 <view class="cut" bindtap="cutNumber">-</view>
                 <input value="{{number}}" class="number" disabled="true" type="number" />
-                <view class="add" bindtap="addNumber">+</view>
+                <!-- <view class="add" bindtap="addNumber">+</view> -->
+                <view class="{{number+cartNumber>= stockNum? 'addEnabel':'add'}}" bindtap="{{number+cartNumber>= stockNum ? '':'addNumber'}}">+</view>
               </view>
             </view>
           </view>

+ 10 - 2
wx-mall/pages/category/category.wxss

@@ -83,7 +83,8 @@ color: transparent;
   padding: 0 6.25rpx;
   height: auto;
   overflow: hidden;
-  margin-bottom: 400rpx;
+  /* margin-bottom: 400rpx; */
+  margin-bottom: 250rpx;
 }
 
 .cate-item .b .item{
@@ -170,7 +171,7 @@ color: transparent;
 }
 
 .attr-pop .info {
-  float: left;
+  /* float: left; */
   height: 177rpx;
   display: flex;
   align-items: flex-start;
@@ -288,4 +289,11 @@ color: transparent;
   flex: 1;
   text-align: center;
   color: #fff;
+}
+.addEnabel {
+  width: 93.75rpx;
+  height: 100%;
+  text-align: center;
+  line-height: 65rpx;
+  color: #ccc;
 }

+ 39 - 16
wx-mall/pages/goods/goods.js

@@ -40,7 +40,10 @@ Page({
     startX:0,
     curr_id: '',
     videoHiddenName: true,
-    imgHiddenName: false
+    imgHiddenName: false,
+    page: 1,
+    size: 4,
+    detailContent: ''
   },
   toggleNav() {
     this.setData({
@@ -53,11 +56,20 @@ Page({
       url: `/pages/${name}/${name}`,
     });
   },
+  //小程序里的转义方法
+  escape2Html: function (str) {
+    var arrEntities = { 'lt': '<', 'gt': '>', 'nbsp': ' ', 'amp': '&', 'quot': '"' };
+    return str.replace(/&(lt|gt|nbsp|amp|quot);/ig, function (all, t) { return arrEntities[t]; });
+  },
+//调用在需要的地方直接调用即可。如:this.escape2Html(contents)
   getGoodsInfo: function () {
     wx.showLoading({
       title: '加载中...',
     });
+    setTimeout(function () {
+    }, 350)
     let that = this;
+    const regex = new RegExp('<img', 'gi');
     util.request(api.GoodsDetail, { id: that.data.id, referrer: this.data.referrer, 
       merchSn: wx.getStorageSync('merchSn') }).then(function (res) {
       if (res.errno === 0) {
@@ -74,7 +86,8 @@ Page({
           stockNum: res.data.stockNum,
           cartNumber: res.data.cartNumber,
           defaultFreight: res.data.defaultFreight,
-          checkedSpecText: res.data.specificationList[0].valueList[0].value
+          checkedSpecText: res.data.specificationList[0].valueList[0].value,
+          detailContent: that.escape2Html(res.data.info.goods_desc).replace(regex, `<img style="width: 100%;"`)
         });
 
         if (res.data.userHasCollect == 1) {
@@ -87,7 +100,7 @@ Page({
           });
         }
 
-        WxParse.wxParse('goodsDetail', 'html', res.data.info.goods_desc, that);
+        // WxParse.wxParse('goodsDetail', 'html', res.data.info.goods_desc, that);
 
         that.getGoodsRelated();
 
@@ -138,18 +151,6 @@ Page({
       }
     });
   },
-
-  getGoodsRelated: function () {
-    let that = this;
-    util.request(api.GoodsRelated, { id: that.data.id }).then(function (res) {
-      if (res.errno === 0) {
-        that.setData({
-          relatedGoods: res.data.goodsList,
-        });
-      }
-    });
-
-  },
   clickSkuValue: function (event) {
     let that = this;
     let specNameId = event.currentTarget.dataset.nameId;
@@ -387,9 +388,9 @@ Page({
         //找不到对应的product信息,提示没有库存
         return false;
       }
-
       // //根据选中的规格,判断是否有对应的sku信息
       let checkedProduct = goodsUtil.getCheckedProductItem(goodsUtil.getCheckedSpecKey(that), that);
+      console.log(checkedProduct)
       if (!checkedProduct || checkedProduct.length <= 0) {
         wx.showToast({
           title: '库存不足',
@@ -574,5 +575,27 @@ Page({
       videoHiddenName: true
     })
     this.videoContext.pause();
+  },
+  getGoodsRelated: function () {
+    let that = this;
+    util.request(api.GoodsRelated, { id: that.data.id, page: that.data.page, size: that.data.size }).then(function (res) {
+      if (res.errno === 0) {
+        let goodsList = that.data.relatedGoods.concat(res.data.goodsList);
+        that.setData({
+          relatedGoods: goodsList,
+        });
+      }
+    });
+
+  },
+  onReachBottom() {
+    var that = this;
+    wx.showLoading({
+      title: '加载中...',
+    })
+    that.setData({
+      page: that.data.page + 1
+    });
+    that.getGoodsRelated();
   }
 })

+ 6 - 3
wx-mall/pages/goods/goods.wxml

@@ -206,8 +206,11 @@
     </view>
     <view class="detail"  bindtap="hideSwitchAttrPop">
       <view class="t">商品详情</view>
-      <import src="../../lib/wxParse/wxParse.wxml"/>
-      <template is="wxParse" data="{{wxParseData:goodsDetail.nodes}}" />
+      <view style="margin-left: 20rpx;" x:if="{{detailContent != ''}}">
+        <rich-text nodes="{{detailContent}}"></rich-text>
+      </view>
+      <!-- <import src="../../lib/wxParse/wxParse.wxml"/>
+      <template is="wxParse" data="{{wxParseData:goodsDetail.nodes}}" /></view> -->
     </view>
 
 
@@ -251,7 +254,7 @@
   <view wx:if="{{openAttr}}" class="attr-pop">
     <view class="attr-close" bindtap="switchAttrPop">X</view>
     <view class="img-info">
-      <image class="img" src="{{goods.list_pic_url}}"></image>
+      <view><image class="img" src="{{goods.list_pic_url}}"></image></view>
       <view class="info">
         <view class="c">
           <view class="p">价格:¥{{goods.retail_price}}</view>

+ 1 - 1
wx-mall/pages/goods/goods.wxss

@@ -897,7 +897,7 @@
 }
 
 .attr-pop .info {
-  float: left;
+  /* float: left; */
   height: 177rpx;
   display: flex;
   align-items: center;

+ 40 - 9
wx-mall/pages/hotGoods/hotGoods.js

@@ -13,10 +13,10 @@ Page({
     filterCategory: [],
     goodsList: [],
     categoryId: 0,
-    currentSortType: 'default',
-    currentSortOrder: 'desc',
+    currentSortType: 'desc',
+    currentSortOrder: 'a.create_time',
     page: 1,
-    size: 1000,
+    size: 4,
     showNavList: false,
     footCart: {},
     openAttr: false,
@@ -27,6 +27,7 @@ Page({
     retailPrice: '',
     stockNum: 0,
     cartNumber: 0,
+    totalPages: 0
   },
   toggleNav() {
     this.setData({
@@ -36,9 +37,11 @@ Page({
   getData: function () {
     let that = this;
     util.request(api.GoodsHot).then(function (res) {
-      if (res.errno === 0) {
+      if (res.errno == 0) {
         that.setData({
           bannerInfo: res.data.bannerInfo,
+          goodsList: [],
+          page: 1
         });
         that.getGoodsList();
       }
@@ -53,9 +56,11 @@ Page({
     util.request(api.HotGoodsList, { isHot: 1, page: that.data.page, size: that.data.size, order: that.data.currentSortOrder, sort: that.data.currentSortType, categoryId: that.data.categoryId})
       .then(function (res) {
         if (res.errno === 0) {
+          let goodsList = that.data.goodsList.concat(res.data.goodsList);
           that.setData({
-            goodsList: res.data.goodsList,
-            filterCategory: res.data.filterCategory
+            goodsList: goodsList,
+            filterCategory: res.data.filterCategory,
+            totalPages: 0
           });
           wx.hideLoading();
           if(that.data.categoryId>0){
@@ -118,7 +123,9 @@ Page({
         this.setData({
           'currentSortType': 'price',
           'currentSortOrder': tmpSortOrder,
-          'categoryFilter': false
+          'categoryFilter': false,
+          goodsList: [],
+          page: 1
         });
 
         this.getData();
@@ -128,7 +135,9 @@ Page({
         this.setData({
           'currentSortType': 'default',
           'currentSortOrder': 'desc',
-          'categoryFilter': false
+          'categoryFilter': false,
+          goodsList: [],
+          page: 1
         });
         this.getData();
     }
@@ -174,13 +183,23 @@ Page({
       goodsId: goodsId
     }).then(function (res) {
       if (res.errno === 0 && null != res.data) {
+        let stockNumbers = 0;
+        if (res.data.goodsVo.goodsBizType == '00') {
+          if (res.data.goodsVo.isStockShare == 1) {
+            stockNumbers = res.data.goodsVo.goods_number;
+          } else {
+            stockNumbers = res.data.goodsVo.stockNum;
+          }
+        } else {
+          stockNumbers = res.data.goodsVo.stockNum;
+        }
         that.setData({
           goodsVo: res.data.goodsVo,
           specificationList: res.data.specificationList,
           productList: res.data.productList,
           openAttr: !that.data.openAttr,
           retailPrice: retailPrice,
-          stockNum: res.data.productList[0].stock_num,
+          stockNum: stockNumbers,
           cartNumber: res.data.cartNumber,
           checkedSpecText: res.data.specificationList[0].valueList[0].value
         });
@@ -279,4 +298,16 @@ Page({
       }
     });
   },
+  onReachBottom() {
+    var that = this;
+    if (!that.data.goodsList) {
+      wx.showLoading({
+        title: '加载中...',
+      })
+    }
+    that.setData({
+      page: that.data.page + 1,
+    });
+    that.getGoodsList();
+  }
 })

+ 1 - 0
wx-mall/pages/hotGoods/hotGoods.wxml

@@ -102,6 +102,7 @@
         <view class="c">
           <view class="p">价格:¥{{retailPrice}}</view>
           <view class="a" wx:if="{{productList.length>0}}">已选择:{{checkedSpecText}}</view>
+          <view class="a">库存{{goodsVo.goodsBizType==00 && goodsVo.isStockShare==1?goodsVo.goods_number:goodsVo.stockNum}}件</view>
         </view>
       </view>
     </view>

+ 1 - 1
wx-mall/pages/hotGoods/hotGoods.wxss

@@ -221,7 +221,7 @@ page{
 }
 
 .attr-pop .info {
-  float: left;
+  /* float: left; */
   height: 177rpx;
   display: flex;
   align-items: flex-start;

+ 125 - 22
wx-mall/pages/index/index.js

@@ -17,7 +17,11 @@ Page({
     storeName: '',
     showPop: false,//活动弹窗
     couponVo: {},
-    storeId: ''
+    storeId: '',
+    page: 1,
+    size: 3,
+    list: [],
+    openAttr: false,
   },
   showCouponPop() {
     let that = this;
@@ -42,13 +46,18 @@ Page({
     }
   },
   getIndexData: function () {
+    setTimeout(function () {
+    }, 350)
+    wx.showLoading({
+      title: '加载中...',
+    })
     let that = this;
     util.request(api.IndexUrl).then(function (res) {
       if (res.errno === 0) {
         // console.log(res.data.banner);
         that.setData({
           // newGoods: res.data.newGoodsList,
-          hotGoods: res.data.hotGoodsList,
+          // hotGoods: res.data.hotGoodsList,
           // topics: res.data.topicList,
           // brand: res.data.brandList,
           // floorGoods: res.data.categoryList,
@@ -56,6 +65,28 @@ Page({
           // groupBanner: res.data.groupBanner,
           channel: res.data.channel
         });
+        if (that.data.hotGoods.length==0){
+          that.getGoodsList();
+        }
+      }
+      wx.hideLoading();
+    });
+  },
+  getGoodsList: function(){
+    let that = this;
+    util.request(api.GoodsHot).then(function (res) {
+      if (res.errno == 0) {
+        util.request(api.HotGoodsList, { isHot: 1, page: that.data.page, size: that.data.size, categoryId: 0 })
+          .then(function (res) {
+            if (res.errno == 0) {
+              let goodsList = that.data.hotGoods.concat(res.data.goodsList);
+              that.setData({
+                hotGoods: goodsList,
+                list: res.data.goodsList
+              });
+            }
+          });
+        wx.hideLoading();
       }
     });
   },
@@ -120,7 +151,7 @@ Page({
     // console.log('dataset.goodsBizType:' + e.currentTarget.dataset.goodsBizType);
     app.globalData.appGoodsBizType = e.currentTarget.dataset.goodsBizType;
     // console.log('appgoodsBizType1:' + app.globalData.appGoodsBizType);
-    
+
     wx.switchTab({
       url: '/pages/catalog/catalog',
     });
@@ -139,11 +170,11 @@ Page({
   },
   reLoad: function () {
     let that = this;
-      // console.log(wx.getStorageSync('userId'));
-      // console.log(wx.getStorageSync('storeId'));
-      // console.log(wx.getStorageSync('merchSn'));
+    // console.log(wx.getStorageSync('userId'));
+    // console.log(wx.getStorageSync('storeId'));
+    // console.log(wx.getStorageSync('merchSn'));
     if (wx.getStorageSync('storeId')) {
-      if (wx.getStorageSync('userId')){
+      if (wx.getStorageSync('userId')) {
         wx.request({
           url: api.updateLoginUser,
           data: {
@@ -215,10 +246,10 @@ Page({
         }
       })
     });
-    
+
   },
   // 更新门店Id
-  chooseStore: function (storeId,merchSn) {
+  chooseStore: function (storeId, merchSn) {
     let that = this;
     util.request(api.ChooseStoreId, { storeId: storeId, merchSn: merchSn }, 'POST').then(function (res) {
       if (res.errno === 0) {
@@ -342,7 +373,7 @@ Page({
           // var goodId = that.value.substring(18, that.value.length);
           var scanArray = that.value.split('&');
           // console.log(scanArray.length);
-          if (scanArray.length < 2){
+          if (scanArray.length < 2) {
             wx.showModal({
               title: '',
               content: '您所扫描的商品无效',
@@ -375,21 +406,23 @@ Page({
               content: '该商品不属于当前门店',
               showCancel: false
             });
-            return;         
+            return;
           }
           util.request(api.GoodsDetail, { id: goodId, referrer: '' }).then(function (res) {
             if (res.errno === 0) {
               console.log(res);
               // 跳转页面
-              wx.navigateTo({
-                url: that.value,
-                success: function (e) {
-                  console.log('跳转成功');
-                },
-                fail: function (e) {
-                  console.log('跳转失败');
-                }
-              })
+              setTimeout(function () {
+                wx.navigateTo({
+                  url: that.value,
+                  success: function (e) {
+                    console.log('跳转成功');
+                  },
+                  fail: function (e) {
+                    console.log('跳转失败');
+                  }
+                })
+              }, 350)
             } else {
               wx.showModal({
                 title: '扫描结果',
@@ -398,7 +431,7 @@ Page({
               });
             }
           });
-        }else{//其他码
+        } else {//其他码
           //弹框显示结果
           wx.showModal({
             title: '扫描结果',
@@ -418,7 +451,7 @@ Page({
       }
 
     })
-  }, 
+  },
   imgOnLoad: function (e) {
     let that = this;
     // console.log('图片加载完成');
@@ -433,11 +466,81 @@ Page({
     //   })
     // }
   },
+  switchAttrPop: function () {
+    this.setData({
+      openAttr: !this.data.openAttr
+    })
+  },
+  hideSwitchAttrPop: function () {
+    this.setData({
+      openAttr: false
+    })
+  },
+  //购物车增加
+  addCart: function (e) {
+    let that = this;
+    that.setData({
+      number: 1
+    });
+    var goodsId = e.currentTarget.dataset.goodsId;
+    var retailPrice = e.currentTarget.dataset.retailPrice;
+    util.request(api.GoodsSku, {
+      goodsId: goodsId
+    }).then(function (res) {
+      if (res.errno === 0 && null != res.data) {
+        let stockNumbers = 0;
+        if (res.data.goodsVo.goodsBizType == '00') {
+          if (res.data.goodsVo.isStockShare == 1) {
+            stockNumbers = res.data.goodsVo.goods_number;
+          } else {
+            stockNumbers = res.data.goodsVo.stockNum;
+          }
+        } else {
+          stockNumbers = res.data.goodsVo.stockNum;
+        }
+        that.setData({
+          goodsVo: res.data.goodsVo,
+          specificationList: res.data.specificationList,
+          productList: res.data.productList,
+          openAttr: !that.data.openAttr,
+          retailPrice: retailPrice,
+          stockNum: stockNumbers,
+          cartNumber: res.data.cartNumber,
+          checkedSpecText: res.data.specificationList[0].valueList[0].value
+        });
+        //
+        let _specificationList = res.data.specificationList;
+        for (let i = 0; i < _specificationList.length; i++) {
+          if (_specificationList[i].valueList.length == 1) {
+            //如果已经选中,则反选
+            _specificationList[i].valueList[0].checked = true;
+          }
+        }
+        that.setData({
+          'specificationList': _specificationList
+        });
+
+      }
+    });
+  },
 
   shows: function (e) {
 
     wx.redirectTo({
       url: '/pages/images/images'
     })
+  },
+  onReachBottom() {
+    var that = this; 
+    if (that.data.list.length > 0) {
+      console.log(that.data.list)
+      wx.showLoading({
+        title: '加载中...',
+      })
+    }
+    that.setData({
+      page: that.data.page + 1
+    });
+    that.getGoodsList();
   }
 })

+ 9 - 3
wx-mall/pages/index/index.wxml

@@ -30,9 +30,11 @@
 
   <swiper class="banner" indicator-dots="true" autoplay="true" interval="15000" duration="750">
     <swiper-item wx:for="{{banner}}" wx:key="{{item.id}}">
+    <scroll-view class='contents fade_in}}'>
       <navigator url="{{item.link}}">
-        <image class="swiper-item" src="{{item.imageUrl}}" bindload="imgOnLoad"  mode="aspectFill" background-size="cover"></image>
+        <image lazy-load="true" class="swiper-item" src="{{item.imageUrl}}" bindload="imgOnLoad"  mode="aspectFill" background-size="cover"></image>
       </navigator>
+    </scroll-view>
     </swiper-item>
   </swiper>
   <view class="m-menu">
@@ -56,6 +58,10 @@
       <image src="../../static/images/service-smgw.png" background-size="cover"></image>
       <text>扫码购物</text>
     </navigator>
+    <!-- <navigator class="itemb" bindtap="shows">
+      <image src="../../static/images/service-smgw.png" background-size="cover"></image>
+      <text>图片</text>
+    </navigator> -->
 
   </view>
   <!-- <view class="m-menu">
@@ -175,13 +181,13 @@
               <text class="price">{{item.retail_price?"¥"+item.retail_price:"0"}}</text>
               <text class="org-price line-through">{{item.market_price?"¥"+item.market_price:""}}</text>
               <!-- //数量加减 -->
-              <view class="number-item">
+              <!-- <view class="number-item">
                 <view class="selnum">
                   <view class="cut" data-goods-id="{{item.id}}" data-product-id="{{item.product_id}}" bindtap="cutNumber"></view>
                   <input value="{{item.cart_num}}" class="number" disabled="true" type="number" />
                   <view class="add" data-goods-id="{{item.id}}" data-product-id="{{item.product_id}}" bindtap="addNumber"></view>
                 </view>
-              </view>
+              </view> -->
             </view>
           </view>
         </view>

+ 200 - 179
wx-mall/pages/search/search.js

@@ -3,203 +3,224 @@ var api = require('../../config/api.js');
 
 var app = getApp()
 Page({
-    data: {
-        keywrod: '',
-        searchStatus: false,
-        goodsList: [],
-        helpKeyword: [],
-        historyKeyword: [],
-        categoryFilter: false,
-        filterCategory: [],
-        defaultKeyword: {},
-        hotKeyword: [],
-        page: 1,
-        size: 1000,
-        currentSortType: 'id',
-        currentSortOrder: 'desc',
-        categoryId: 0,
-        showNavList: false,
-        footCart: {}
-    },
-    toggleNav() {
-        this.setData({
-            showNavList: !this.data.showNavList
-        })
-    },
-    switchNav(event) {
-        let name = event.currentTarget.dataset.name;
-        wx.switchTab({
-            url: `/pages/${name}/${name}`,
-        });
-    },
-    //事件处理函数
-    closeSearch: function () {
-        wx.navigateBack()
-    },
-    clearKeyword: function () {
-        this.setData({
-            keyword: '',
-            searchStatus: false
-        });
-    },
-    onLoad: function () {
-        this.getSearchKeyword();
-        this.getFootCart();
-    },
+  data: {
+    keywrod: '',
+    searchStatus: false,
+    goodsList: [],
+    helpKeyword: [],
+    historyKeyword: [],
+    categoryFilter: false,
+    filterCategory: [],
+    defaultKeyword: {},
+    hotKeyword: [],
+    page: 1,
+    size: 1000,
+    currentSortType: 'id',
+    currentSortOrder: 'desc',
+    categoryId: 0,
+    showNavList: false,
+    footCart: {},
+    page: 1,
+    size: 6
+  },
+  toggleNav() {
+    this.setData({
+      showNavList: !this.data.showNavList
+    })
+  },
+  switchNav(event) {
+    let name = event.currentTarget.dataset.name;
+    wx.switchTab({
+      url: `/pages/${name}/${name}`,
+    });
+  },
+  //事件处理函数
+  closeSearch: function () {
+    wx.navigateBack()
+  },
+  clearKeyword: function () {
+    this.setData({
+      keyword: '',
+      searchStatus: false
+    });
+  },
+  onLoad: function () {
+    this.getSearchKeyword();
+    this.getFootCart();
+  },
 
-    getFootCart: function () {
-        let that = this;
-        util.request(api.GetFootCart).then(function (res) {
-            if (res.errno === 0) {
-                that.setData({
-                    footCart: res.data,
-                });
-            }
+  getFootCart: function () {
+    let that = this;
+    util.request(api.GetFootCart).then(function (res) {
+      if (res.errno === 0) {
+        that.setData({
+          footCart: res.data,
         });
-    },
-    getSearchKeyword() {
-        let that = this;
-        util.request(api.SearchIndex).then(function (res) {
-            if (res.errno === 0) {
-                that.setData({
-                    historyKeyword: res.data.historyKeywordList,
-                    defaultKeyword: res.data.defaultKeyword,
-                    hotKeyword: res.data.hotKeywordList
-                });
-            }
+      }
+    });
+  },
+  getSearchKeyword() {
+    let that = this;
+    util.request(api.SearchIndex).then(function (res) {
+      if (res.errno === 0) {
+        that.setData({
+          historyKeyword: res.data.historyKeywordList,
+          defaultKeyword: res.data.defaultKeyword,
+          hotKeyword: res.data.hotKeywordList
         });
-    },
+      }
+    });
+  },
 
-    inputChange: function (e) {
+  inputChange: function (e) {
 
-        this.setData({
-            keyword: e.detail.value,
-            searchStatus: false
-        });
-        this.getHelpKeyword();
-    },
-    getHelpKeyword: function () {
-        let that = this;
-        util.request(api.SearchHelper, { keyword: that.data.keyword }).then(function (res) {
-            if (res.errno === 0) {
-                that.setData({
-                    helpKeyword: res.data
-                });
-            }
-        });
-    },
-    inputFocus: function () {
-        this.setData({
-            searchStatus: false,
-            goodsList: []
+    this.setData({
+      keyword: e.detail.value,
+      searchStatus: false
+    });
+    this.getHelpKeyword();
+  },
+  getHelpKeyword: function () {
+    let that = this;
+    util.request(api.SearchHelper, { keyword: that.data.keyword }).then(function (res) {
+      if (res.errno === 0) {
+        that.setData({
+          helpKeyword: res.data
         });
+      }
+    });
+  },
+  inputFocus: function () {
+    this.setData({
+      searchStatus: false,
+      goodsList: []
+    });
 
-        if (this.data.keyword) {
-            this.getHelpKeyword();
-        }
-    },
-    clearHistory: function () {
-        this.setData({
-            historyKeyword: []
-        })
+    if (this.data.keyword) {
+      this.getHelpKeyword();
+    }
+  },
+  clearHistory: function () {
+    this.setData({
+      historyKeyword: []
+    })
 
-        util.request(api.SearchClearHistory, {}, 'POST')
-            .then(function (res) {
-                console.log('清除成功');
-            });
-    },
-    getGoodsList: function () {
-      let that = this;
-      wx.showLoading({
-        title: '加载中...',
+    util.request(api.SearchClearHistory, {}, 'POST')
+      .then(function (res) {
+        console.log('清除成功');
       });
-        util.request(api.GoodsList, { keyword: that.data.keyword, page: that.data.page, size: that.data.size, sort: that.data.currentSortType, order: that.data.currentSortOrder, categoryId: that.data.categoryId,
-        storeId:wx.getStorageSync("storeId")}).then(function (res) {
-            if (res.errno === 0) {
-                that.setData({
-                    searchStatus: true,
-                    categoryFilter: false,
-                    goodsList: res.data.data,
-                    filterCategory: res.data.filterCategory,
-                    page: res.data.currentPage,
-                    size: res.data.numsPerPage
-              });
-              wx.hideLoading();
-            }
-
-            //重新获取关键词
-            that.getSearchKeyword();
+  },
+  getGoodsList: function () {
+    let that = this;
+    wx.showLoading({
+      title: '加载中...',
+    });
+    util.request(api.GoodsList, {
+      keyword: that.data.keyword, page: that.data.page, size: that.data.size, sort: that.data.currentSortType, order: that.data.currentSortOrder, categoryId: that.data.categoryId,
+      storeId: wx.getStorageSync("storeId")
+    }).then(function (res) {
+      if (res.errno === 0) {
+        let goodsList = that.data.goodsList.concat(res.data.data);
+        that.setData({
+          searchStatus: true,
+          categoryFilter: false,
+          goodsList: goodsList,
+          filterCategory: res.data.filterCategory,
+          page: res.data.currentPage,
+          size: res.data.numsPerPage
         });
-    },
-    onKeywordTap: function (event) {
+        wx.hideLoading();
+      }
+
+      //重新获取关键词
+      that.getSearchKeyword();
+    });
+  },
+  onKeywordTap: function (event) {
 
-        this.getSearchResult(event.target.dataset.keyword);
+    this.getSearchResult(event.target.dataset.keyword);
 
-    },
-    getSearchResult(keyword) {
+  },
+  getSearchResult(keyword) {
+    this.setData({
+      keyword: keyword,
+      categoryId: 0,
+      page: 1,
+      goodsList: []
+    });
+
+    this.getGoodsList();
+  },
+  openSortFilter: function (event) {
+    let currentId = event.currentTarget.id;
+    switch (currentId) {
+      case 'categoryFilter':
         this.setData({
-            keyword: keyword,
-            page: 1,
-            categoryId: 0,
-            goodsList: []
+          'categoryFilter': !this.data.categoryFilter,
+          'currentSortOrder': 'asc'
+        });
+        break;
+      case 'priceSort':
+        let tmpSortOrder = 'asc';
+        if (this.data.currentSortOrder == 'asc') {
+          tmpSortOrder = 'desc';
+        }
+        this.setData({
+          'currentSortType': 'price',
+          'currentSortOrder': tmpSortOrder,
+          'categoryFilter': false,
+          page: 1,
+          goodsList: []
         });
 
         this.getGoodsList();
-    },
-    openSortFilter: function (event) {
-        let currentId = event.currentTarget.id;
-        switch (currentId) {
-            case 'categoryFilter':
-                this.setData({
-                    'categoryFilter': !this.data.categoryFilter,
-                    'currentSortOrder': 'asc'
-                });
-                break;
-            case 'priceSort':
-                let tmpSortOrder = 'asc';
-                if (this.data.currentSortOrder == 'asc') {
-                    tmpSortOrder = 'desc';
-                }
-                this.setData({
-                    'currentSortType': 'price',
-                    'currentSortOrder': tmpSortOrder,
-                    'categoryFilter': false
-                });
-
-                this.getGoodsList();
-                break;
-            default:
-                //综合排序
-                this.setData({
-                    'currentSortType': 'default',
-                    'currentSortOrder': 'desc',
-                    'categoryFilter': false
-                });
-                this.getGoodsList();
-        }
-    },
-    selectCategory: function (event) {
-        let currentIndex = event.target.dataset.categoryIndex;
-        let filterCategory = this.data.filterCategory;
-        let currentCategory = null;
-        for (let key in filterCategory) {
-            if (key == currentIndex) {
-                filterCategory[key].selected = true;
-                currentCategory = filterCategory[key];
-            } else {
-                filterCategory[key].selected = false;
-            }
-        }
+        break;
+      default:
+        //综合排序
         this.setData({
-            'filterCategory': filterCategory,
-            'categoryFilter': false,
-            categoryId: currentCategory.id,
-            page: 1,
-            goodsList: []
+          'currentSortType': 'default',
+          'currentSortOrder': 'desc',
+          'categoryFilter': false,
+          page: 1,
+          goodsList: []
         });
         this.getGoodsList();
-    },
-    onKeywordConfirm(event) {
-        this.getSearchResult(event.detail.value);
     }
+  },
+  selectCategory: function (event) {
+    let currentIndex = event.target.dataset.categoryIndex;
+    let filterCategory = this.data.filterCategory;
+    let currentCategory = null;
+    for (let key in filterCategory) {
+      if (key == currentIndex) {
+        filterCategory[key].selected = true;
+        currentCategory = filterCategory[key];
+      } else {
+        filterCategory[key].selected = false;
+      }
+    }
+    this.setData({
+      'filterCategory': filterCategory,
+      'categoryFilter': false,
+      categoryId: currentCategory.id,
+      page: 1,
+      goodsList: []
+    });
+    this.getGoodsList();
+  },
+  onKeywordConfirm(event) {
+    this.getSearchResult(event.detail.value);
+  },
+  onReachBottom() {
+    var that = this;
+    if (!that.data.goodsList) {
+      wx.showLoading({
+        title: '加载中...',
+      })
+    }
+    that.setData({
+      page: that.data.page + 1
+    });
+    that.getGoodsList();
+  }
 })

+ 21 - 7
wx-mall/pages/ucenter/addressAdd/addressAdd.js

@@ -420,7 +420,7 @@ Page({
     var that = this;
     wx.chooseLocation({
       success: function (res) {
-        console.log("res:" + res);
+        // console.log("res:" + res);
         let address = that.data.address;
         if(null==res.latitude){
           return;
@@ -431,8 +431,18 @@ Page({
         if (!(province = regex.exec(res.address))) {
           regex = /^(.*?(省|自治区))(.*?)$/;
           province = regex.exec(res.address);
-          address.provinceName = province[1];
-          address = that.regexAddress(province[3], address, res.name);
+          if (province != null) {
+            address.provinceName = province[1];
+            // console.log("试试:" + province[3]);
+            // console.log("试试:" + res.name);
+            // console.log(address);
+            address = that.regexAddress(province[3], address, res.name);
+          }else{
+            wx.showToast({
+              title: '收货地址请详细区县/区镇',
+              icon: 'none'
+            })
+          }
         } else {
           address.provinceName = province[1];
           address = that.regexAddress(res.address, address, res.name);
@@ -448,11 +458,15 @@ Page({
     })
   },
   regexAddress: function (address, addressBean, name) {
-    var regex = /^(.*?[市州]|.*?地区|.*?特别行政区)(.*?[市区县])(.*?)$/g;
+    // var regex = /^(.*?[市州]|.*?地区|.*?特别行政区)(.*?[市区县])(.*?)$/g;
+    var regex = /^(.*?[市州]|.*?地区|.*?特别行政区.*?区|.+盟|市辖区|.*?市|.*?县)(.*?[市区县]|.*?镇|.+海域|.+岛|.*?街|.*?路|.*?道)(.*?)$/g;
+    // var regex = /^(.*?)(.*?)(.*?)$/g;
     var addxress = regex.exec(address);
-    addressBean.cityName = addxress[1];
-    addressBean.countyName = addxress[2];
-    addressBean.detailInfo = addxress[3] + "(" + name + ")";
+    if (addxress != null) {
+      addressBean.cityName = addxress[1];
+      addressBean.countyName = addxress[2];
+      addressBean.detailInfo = addxress[3] + "(" + name + ")";
+    }
     return addressBean;
   }
 })

+ 15 - 12
wx-mall/pages/ucenter/order/order.js

@@ -1,5 +1,7 @@
 var util = require('../../../utils/util.js');
 var api = require('../../../config/api.js');
+//获取应用实例
+const app = getApp();
 
 Page({
     data: {
@@ -104,18 +106,19 @@ Page({
       //   });
       //   return;
       // }
-        util.request(api.CartAddByOrder, {orderId: orderId}).then(function (res) {
-            if (res.errno === 0) {
-                wx.switchTab({
-                    url: '/pages/cart/cart',
-                });
-            } else {
-                wx.showToast({
-                    title: res.errmsg,
-                    image: '/static/images/icon_error.png',
-                    duration: 2000
-                });
-            }
+      util.request(api.CartAddByOrder, { orderId: orderId }).then(function (res) {
+        if (res.errno === 0) {
+          app.globalData.appCheckCart = '00';
+          wx.switchTab({
+            url: '/pages/cart/cart',
+          });
+        } else {
+          wx.showToast({
+            title: res.errmsg,
+            image: '/static/images/icon_error.png',
+            duration: 2000
+          });
+        }
         });
   },
   againBuyDisabel(event) {