Browse Source

Merge remote-tracking branch 'upsteam/master'

zhh 3 years ago
parent
commit
db65a558dd
42 changed files with 1949 additions and 98 deletions
  1. 143 0
      kmall-admin/src/main/java/com/kmall/admin/controller/haikong/StockChangeRecordController.java
  2. 7 0
      kmall-admin/src/main/java/com/kmall/admin/dao/GoodsDao.java
  3. 4 0
      kmall-admin/src/main/java/com/kmall/admin/dao/ProductStoreRelaDao.java
  4. 33 0
      kmall-admin/src/main/java/com/kmall/admin/dao/haikong/StockChangeRecordDao.java
  5. 81 0
      kmall-admin/src/main/java/com/kmall/admin/dto/StockChangeRecordDto.java
  6. 8 0
      kmall-admin/src/main/java/com/kmall/admin/entity/OrderGoodsEntity.java
  7. 4 0
      kmall-admin/src/main/java/com/kmall/admin/entity/haikong/HaiKongMemberOrderSyncResendEntity.java
  8. 3 0
      kmall-admin/src/main/java/com/kmall/admin/entity/haikong/HaiKongMemberScoreChangeRecordEntity.java
  9. 202 0
      kmall-admin/src/main/java/com/kmall/admin/entity/haikong/StockChangeRecordEntity.java
  10. 33 0
      kmall-admin/src/main/java/com/kmall/admin/haikong/constant/Constants.java
  11. 15 0
      kmall-admin/src/main/java/com/kmall/admin/service/GoodsService.java
  12. 2 0
      kmall-admin/src/main/java/com/kmall/admin/service/MngChangeService.java
  13. 13 0
      kmall-admin/src/main/java/com/kmall/admin/service/ProductStoreRelaService.java
  14. 2 0
      kmall-admin/src/main/java/com/kmall/admin/service/StoreMngChangeService.java
  15. 86 0
      kmall-admin/src/main/java/com/kmall/admin/service/haikong/StockChangeRecordService.java
  16. 81 1
      kmall-admin/src/main/java/com/kmall/admin/service/impl/GoodsServiceImpl.java
  17. 5 0
      kmall-admin/src/main/java/com/kmall/admin/service/impl/MngChangeServiceImpl.java
  18. 100 72
      kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java
  19. 80 0
      kmall-admin/src/main/java/com/kmall/admin/service/impl/ProductStoreRelaServiceImpl.java
  20. 5 0
      kmall-admin/src/main/java/com/kmall/admin/service/impl/StoreMngChangeServiceImpl.java
  21. 177 0
      kmall-admin/src/main/java/com/kmall/admin/service/impl/haikong/StockChangeRecordServiceImpl.java
  22. 23 0
      kmall-admin/src/main/resources/XmlTemplate/StockChangeRecordDtoList.xml
  23. 2 2
      kmall-admin/src/main/resources/logback.xml
  24. 37 0
      kmall-admin/src/main/resources/mybatis/mapper/GoodsDao.xml
  25. 27 0
      kmall-admin/src/main/resources/mybatis/mapper/ProductStoreRelaDao.xml
  26. 40 0
      kmall-admin/src/main/resources/mybatis/mapper/StoreMngChangeDao.xml
  27. 146 0
      kmall-admin/src/main/resources/mybatis/mapper/haikong/StockChangeRecordDao.xml
  28. 4 1
      kmall-admin/src/main/webapp/WEB-INF/page/mk/mkactivitiespromotion.html
  29. 44 10
      kmall-admin/src/main/webapp/WEB-INF/page/sale/sale.html
  30. 7 7
      kmall-admin/src/main/webapp/WEB-INF/page/shop/offilineOrderList.html
  31. 103 0
      kmall-admin/src/main/webapp/WEB-INF/page/shop/stockchangerecord.html
  32. 125 3
      kmall-admin/src/main/webapp/js/sale/sale.js
  33. 4 0
      kmall-admin/src/main/webapp/js/shop/mngchange.js
  34. 238 0
      kmall-admin/src/main/webapp/js/shop/stockchangerecord.js
  35. 4 0
      kmall-admin/src/main/webapp/js/shop/storemngchange.js
  36. BIN
      kmall-admin/src/main/webapp/statics/file/stock_change_record.xlsx
  37. 22 0
      kmall-api/src/main/java/com/kmall/api/api/ApiIndexController.java
  38. 5 2
      kmall-common/src/main/java/com/kmall/common/constant/Dict.java
  39. 2 0
      kmall-common/src/main/java/com/kmall/common/constant/JxlsXmlTemplateName.java
  40. 1 0
      kmall-manager/src/main/resources/conf/redis.properties
  41. 13 0
      sql/init/other_table.sql
  42. 18 0
      sql/init/sys_table.sql

+ 143 - 0
kmall-admin/src/main/java/com/kmall/admin/controller/haikong/StockChangeRecordController.java

@@ -0,0 +1,143 @@
+package com.kmall.admin.controller.haikong;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.kmall.admin.dto.StockChangeRecordDto;
+import com.kmall.admin.entity.haikong.StockChangeRecordEntity;
+import com.kmall.admin.service.haikong.StockChangeRecordService;
+import com.kmall.common.constant.JxlsXmlTemplateName;
+import com.kmall.common.utils.PageUtils;
+import com.kmall.common.utils.Query;
+import com.kmall.common.utils.R;
+import com.kmall.common.utils.excel.ExcelUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+
+/**
+ * 海控出入库单记录Controller
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2021-12-27 16:21:47
+ */
+@Controller
+@RequestMapping("stockchangerecord")
+public class StockChangeRecordController {
+    @Autowired
+    private StockChangeRecordService stockChangeRecordService;
+    @Autowired
+    private ExcelUtil excelUtil;
+
+    private final static Logger log = LoggerFactory.getLogger(StockChangeRecordController.class);
+    /**
+     * 查看列表
+     */
+    @RequestMapping("/list")
+    @ResponseBody
+    public R list(@RequestParam Map<String, Object> params) {
+        //查询列表数据
+        Query query = new Query(params);
+
+        List<StockChangeRecordEntity> stockChangeRecordList = stockChangeRecordService.queryList(query);
+        int total = stockChangeRecordService.queryTotal(query);
+
+        PageUtils pageUtil = new PageUtils(stockChangeRecordList, total, query.getLimit(), query.getPage());
+
+        return R.ok().put("page", pageUtil);
+    }
+
+    /**
+     * 查看信息
+     */
+    @RequestMapping("/info/{id}")
+    @ResponseBody
+    public R info(@PathVariable("id") Integer id) {
+        StockChangeRecordEntity stockChangeRecord = stockChangeRecordService.queryObject(id);
+
+        return R.ok().put("stockChangeRecord", stockChangeRecord);
+    }
+
+    /**
+     * 保存
+     */
+    @RequestMapping("/save")
+    @ResponseBody
+    public R save(@RequestBody StockChangeRecordEntity stockChangeRecord) {
+        stockChangeRecordService.save(stockChangeRecord);
+
+        return R.ok();
+    }
+
+    /**
+     * 修改
+     */
+    @RequestMapping("/update")
+    @ResponseBody
+    public R update(@RequestBody StockChangeRecordEntity stockChangeRecord) {
+        stockChangeRecordService.update(stockChangeRecord);
+
+        return R.ok();
+    }
+
+    /**
+     * 删除
+     */
+    @RequestMapping("/delete")
+    @ResponseBody
+    public R delete(@RequestBody Integer[]ids) {
+        stockChangeRecordService.deleteBatch(ids);
+
+        return R.ok();
+    }
+
+    /**
+     * 查看所有列表
+     */
+    @RequestMapping("/queryAll")
+    @ResponseBody
+    public R queryAll(@RequestParam Map<String, Object> params) {
+
+        List<StockChangeRecordEntity> list = stockChangeRecordService.queryList(params);
+
+        return R.ok().put("list", list);
+    }
+
+    /**
+     * 导入excel
+     */
+    @PostMapping("/upload")
+    @ResponseBody
+    public R storeUpload(@RequestParam("file") MultipartFile file) {
+        List<StockChangeRecordDto> stockChangeRecordDtos = new ArrayList<>();//信息
+        try {
+
+            StockChangeRecordDto stockChangeRecordDto = new StockChangeRecordDto();
+            Map<String, Object> beans = new HashMap<String, Object>();
+            beans.put("StockChangeRecordDto", stockChangeRecordDto);
+            beans.put("StockChangeRecordDtoList", stockChangeRecordDtos);
+            if (file.isEmpty()) {
+                return R.error("文件不能为空!");
+            }
+            excelUtil.readExcel(JxlsXmlTemplateName.STOCK_CHANGE_RECORD_DTO_LIST, beans, file.getInputStream());
+        } catch (Exception e) {
+            log.error("导入出入库记录失败:", e);
+            return R.error("导入失败!");
+        }
+        try {
+            stockChangeRecordService.uploadExcel(stockChangeRecordDtos);
+        } catch (RuntimeException e){
+            log.error("出入库记录导入数据写入表失败:", e);
+            return R.error(e.getMessage());
+        }
+        //上传文件
+        return R.ok("导入成功!");
+    }
+}

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

@@ -3,6 +3,7 @@ package com.kmall.admin.dao;
 import com.kmall.admin.dto.GoodsDetailsDto;
 import com.kmall.admin.dto.GoodsPanoramaDto;
 import com.kmall.admin.entity.GoodsEntity;
+import com.kmall.admin.entity.haikong.StockChangeRecordEntity;
 import com.kmall.admin.haikong.vo.QueryGoodsVO;
 import com.kmall.api.entity.exportpdf.PDFGoodsDto;
 import com.kmall.manager.dao.BaseDao;
@@ -28,6 +29,8 @@ public interface GoodsDao extends BaseDao<GoodsEntity> {
 
     GoodsEntity queryObjectByProdBarcodeAndBizType(@Param("prodBarcode")String prodBarcode, @Param("storeId")Integer storeId);
 
+    GoodsEntity queryObjectByProdBarcodeAndStoreId(@Param("prodBarcode")String prodBarcode, @Param("storeId")Integer storeId);
+
     GoodsEntity queryObjectByProdBarcodeAndStore(@Param("prodBarcode")String prodBarcode, @Param("storeId")Integer storeId);
 
     GoodsDetailsDto queryGoodsDetailsByProdBarcode(@Param("prodBarcode") String prodBarcode, @Param("storeId")String storeId, @Param("sku")String sku);
@@ -131,4 +134,8 @@ public interface GoodsDao extends BaseDao<GoodsEntity> {
      * @return
      */
     int updateStockNumberByProductCodeAndSku(GoodsEntity goodsEntity);
+
+    void updateStockNumberByOutbound(List<StockChangeRecordEntity> outboundList);
+
+    void updateStockNumberByStorage(List<StockChangeRecordEntity> storageList);
 }

+ 4 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/ProductStoreRelaDao.java

@@ -4,6 +4,7 @@ import com.kmall.admin.dto.Mall2RulesDto;
 import com.kmall.admin.entity.ProductStoreRelaEntity;
 import com.kmall.admin.entity.StoreEntity;
 import com.kmall.admin.entity.StoreTransferInventoryOrderDetailEntity;
+import com.kmall.admin.entity.haikong.StockChangeRecordEntity;
 import com.kmall.admin.entity.vip.Mall2DetilEntity;
 import org.apache.ibatis.annotations.Param;
 import com.kmall.manager.dao.BaseDao;
@@ -119,4 +120,7 @@ public interface ProductStoreRelaDao extends BaseDao<ProductStoreRelaEntity> {
 
     ProductStoreRelaEntity queryByGoodsIdAndStoreIdHkMall(@Param("storeId") Long storeId, @Param("goodsId") Long goodsId);
 
+    void updateStockNumberByOutbound(List<StockChangeRecordEntity> outboundList);
+
+    void updateStockNumberByStorage(List<StockChangeRecordEntity> storageList);
 }

+ 33 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/haikong/StockChangeRecordDao.java

@@ -0,0 +1,33 @@
+package com.kmall.admin.dao.haikong;
+
+import com.kmall.admin.entity.haikong.StockChangeRecordEntity;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 海控出入库单记录Dao
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2021-12-27 16:21:47
+ */
+public interface StockChangeRecordDao {
+
+
+    StockChangeRecordEntity queryObject(Integer id);
+
+    List<StockChangeRecordEntity> queryList(Map<String, Object> map);
+
+    int queryTotal(Map<String, Object> map);
+
+    int save(StockChangeRecordEntity stockChangeRecord);
+
+    int update(StockChangeRecordEntity stockChangeRecord);
+
+    int delete(Integer id);
+
+    int deleteBatch(Integer[] ids);
+
+    void saveBatch(List<StockChangeRecordEntity> stockChangeRecordEntities);
+}

+ 81 - 0
kmall-admin/src/main/java/com/kmall/admin/dto/StockChangeRecordDto.java

@@ -0,0 +1,81 @@
+package com.kmall.admin.dto;
+
+import java.io.Serializable;
+
+/**
+ * @author lhm
+ * @createDate 2021-12-27
+ */
+public class StockChangeRecordDto implements Serializable {
+
+    private static final long serialVersionUID = 199865635636920L;
+
+    private Integer storeId;
+
+    private String merchSn;
+    private String thirdMerchSn;
+
+    private String sku;
+
+    private String type;
+
+    private Integer number;
+
+    private String remark;
+
+    public Integer getStoreId() {
+        return storeId;
+    }
+
+    public void setStoreId(Integer storeId) {
+        this.storeId = storeId;
+    }
+
+    public String getSku() {
+        return sku;
+    }
+
+    public void setSku(String sku) {
+        this.sku = sku;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getMerchSn() {
+        return merchSn;
+    }
+
+    public void setMerchSn(String merchSn) {
+        this.merchSn = merchSn;
+    }
+
+    public String getThirdMerchSn() {
+        return thirdMerchSn;
+    }
+
+    public void setThirdMerchSn(String thirdMerchSn) {
+        this.thirdMerchSn = thirdMerchSn;
+    }
+}

+ 8 - 0
kmall-admin/src/main/java/com/kmall/admin/entity/OrderGoodsEntity.java

@@ -381,4 +381,12 @@ public class OrderGoodsEntity implements Serializable {
 	public void setTaxPrice(BigDecimal taxPrice) {
 		this.taxPrice = taxPrice;
 	}
+
+	public Integer getDeductionScore() {
+		return deductionScore;
+	}
+
+	public void setDeductionScore(Integer deductionScore) {
+		this.deductionScore = deductionScore;
+	}
 }

+ 4 - 0
kmall-admin/src/main/java/com/kmall/admin/entity/haikong/HaiKongMemberOrderSyncResendEntity.java

@@ -1,5 +1,7 @@
 package com.kmall.admin.entity.haikong;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
+
 import java.math.BigDecimal;
 import java.util.Date;
 
@@ -54,8 +56,10 @@ public class HaiKongMemberOrderSyncResendEntity {
     /**
      * 最后一次重发时间
      */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
     private Date lastResendTime;
 
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
     private Date createTime;
 
     public Integer getId() {

+ 3 - 0
kmall-admin/src/main/java/com/kmall/admin/entity/haikong/HaiKongMemberScoreChangeRecordEntity.java

@@ -1,5 +1,6 @@
 package com.kmall.admin.entity.haikong;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.kmall.admin.haikong.constant.HaiKongMemberScoreChangeEventEnum;
 
 import java.util.Date;
@@ -46,8 +47,10 @@ public class HaiKongMemberScoreChangeRecordEntity {
      */
     private String statementId;
 
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
     private Date createTime;
 
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
     private Date modifyTime;
 
     /**

+ 202 - 0
kmall-admin/src/main/java/com/kmall/admin/entity/haikong/StockChangeRecordEntity.java

@@ -0,0 +1,202 @@
+package com.kmall.admin.entity.haikong;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 海控出入库单记录实体
+ * 表名 mall_stock_change_record
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2021-12-27 16:21:47
+ */
+public class StockChangeRecordEntity implements Serializable {
+    private static final long serialVersionUID = 987816484146341651L;
+
+    /**
+     * 
+     */
+    private Integer id;
+    /**
+     * 门店id
+     */
+    private Integer storeId;
+    private String merchSn;
+    private String thirdMerchSn;
+    private String orderSn;
+    /**
+     * sku
+     */
+    private String sku;
+    /**
+     * 记录类型,0:出库 1:入库 2:销售出库
+     */
+    private String type;
+    /**
+     * 出库或入库数量
+     */
+    private Integer number;
+    /**
+     * 备注
+     */
+    private String remark;
+    /**
+     * 
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+    private Date createTime;
+    /**
+     * 
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+    private Date modifyTime;
+
+    /**
+     * 设置:
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 获取:
+     */
+    public Integer getId() {
+        return id;
+    }
+    /**
+     * 设置:门店id
+     */
+    public void setStoreId(Integer storeId) {
+        this.storeId = storeId;
+    }
+
+    /**
+     * 获取:门店id
+     */
+    public Integer getStoreId() {
+        return storeId;
+    }
+    /**
+     * 设置:sku
+     */
+    public void setSku(String sku) {
+        this.sku = sku;
+    }
+
+    /**
+     * 获取:sku
+     */
+    public String getSku() {
+        return sku;
+    }
+    /**
+     * 设置:记录类型,0:出库 1:入库
+     */
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * 获取:记录类型,0:出库 1:入库
+     */
+    public String getType() {
+        return type;
+    }
+    /**
+     * 设置:出库或入库数量
+     */
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    /**
+     * 获取:出库或入库数量
+     */
+    public Integer getNumber() {
+        return number;
+    }
+    /**
+     * 设置:备注
+     */
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    /**
+     * 获取:备注
+     */
+    public String getRemark() {
+        return remark;
+    }
+    /**
+     * 设置:
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * 获取:
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+    /**
+     * 设置:
+     */
+    public void setModifyTime(Date modifyTime) {
+        this.modifyTime = modifyTime;
+    }
+
+    /**
+     * 获取:
+     */
+    public Date getModifyTime() {
+        return modifyTime;
+    }
+
+    public String getMerchSn() {
+        return merchSn;
+    }
+
+    public void setMerchSn(String merchSn) {
+        this.merchSn = merchSn;
+    }
+
+    public String getThirdMerchSn() {
+        return thirdMerchSn;
+    }
+
+    public void setThirdMerchSn(String thirdMerchSn) {
+        this.thirdMerchSn = thirdMerchSn;
+    }
+
+    public String getOrderSn() {
+        return orderSn;
+    }
+
+    public void setOrderSn(String orderSn) {
+        this.orderSn = orderSn;
+    }
+
+    @Override
+    public String toString() {
+        return "StockChangeRecordEntity{" +
+                "id=" + id +
+                ", storeId=" + storeId +
+                ", merchSn='" + merchSn + '\'' +
+                ", thirdMerchSn='" + thirdMerchSn + '\'' +
+                ", orderSn='" + orderSn + '\'' +
+                ", sku='" + sku + '\'' +
+                ", type='" + type + '\'' +
+                ", number=" + number +
+                ", remark='" + remark + '\'' +
+                ", createTime=" + createTime +
+                ", modifyTime=" + modifyTime +
+                '}';
+    }
+}

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

@@ -334,4 +334,37 @@ public class Constants {
         }
     }
 
+    public enum StockChangeType {
+        /**
+         * 出库
+         */
+        item_0("0", "出库"),
+        /**
+         * 入库
+         */
+        item_1("1", "入库"),
+        /**
+         * 销售出库
+         */
+        item_2("2", "销售出库"),
+        ;
+
+        private final String type;
+
+        private final String desc;
+
+        StockChangeType(String type, String desc) {
+            this.type = type;
+            this.desc = desc;
+        }
+
+        public String getType() {
+            return type;
+        }
+
+        public String getDesc() {
+            return desc;
+        }
+    }
+
 }

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

@@ -5,6 +5,7 @@ import com.kmall.admin.dto.GoodsDto;
 import com.kmall.admin.dto.GoodsPanoramaDto;
 import com.kmall.admin.entity.GoodsEntity;
 import com.kmall.admin.entity.TaxErrorRecordEntity;
+import com.kmall.admin.entity.haikong.StockChangeRecordEntity;
 import com.kmall.admin.fromcomm.entity.SysUserEntity;
 import com.kmall.admin.haikong.vo.QueryGoodsVO;
 import com.kmall.api.entity.exportpdf.PDFGoodsDto;
@@ -30,6 +31,8 @@ public interface GoodsService {
     GoodsEntity queryObject(Integer id);
 
     GoodsEntity queryObjectByProdBarcodeAndBizType(String prodBarcode, Integer storeId);
+
+    GoodsEntity queryObjectByProdBarcodeAndStoreId(String prodBarcode, Integer storeId);
     /**
      * 分页查询
      *
@@ -252,4 +255,16 @@ public interface GoodsService {
     int updateStockNumberByProductCodeAndSku(GoodsEntity goodsEntity);
 
     void validateWarehouseStock(GoodsDetailsDto goods, String prodBarcode, String sku, String storeId);
+
+    /**
+     * 出库单更新库存(扣减)
+     * @param outboundList  出库sku
+     */
+    void updateStockNumberByOutbound(List<StockChangeRecordEntity> outboundList);
+
+    /**
+     * 入库单更新库存(增加)
+     * @param storageList   入库sku
+     */
+    void updateStockNumberByStorage(List<StockChangeRecordEntity> storageList);
 }

+ 2 - 0
kmall-admin/src/main/java/com/kmall/admin/service/MngChangeService.java

@@ -69,4 +69,6 @@ public interface MngChangeService {
      * @return 删除条数
      */
     int deleteBatch(Integer[] ids);
+
+    void saveBatch(List<MngChangeEntity> changeEntityList);
 }

+ 13 - 0
kmall-admin/src/main/java/com/kmall/admin/service/ProductStoreRelaService.java

@@ -3,6 +3,7 @@ package com.kmall.admin.service;
 import com.kmall.admin.dto.StoreGoodsDto;
 import com.kmall.admin.entity.ProductStoreRelaEntity;
 import com.kmall.admin.entity.StoreTransferInventoryOrderDetailEntity;
+import com.kmall.admin.entity.haikong.StockChangeRecordEntity;
 
 import java.util.List;
 import java.util.Map;
@@ -163,4 +164,16 @@ public interface ProductStoreRelaService {
      * @param productStoreRelaEntity    门店库存实体
      */
     void updateStockNumByStoreIdAndSku(ProductStoreRelaEntity productStoreRelaEntity);
+
+    /**
+     * 出库单更新库存(扣减)
+     * @param outboundList  出库sku
+     */
+    void updateStockNumberByOutbound(List<StockChangeRecordEntity> outboundList);
+
+    /**
+     * 入库单更新库存(增加)
+     * @param storageList   入库sku
+     */
+    void updateStockNumberByStorage(List<StockChangeRecordEntity> storageList);
 }

+ 2 - 0
kmall-admin/src/main/java/com/kmall/admin/service/StoreMngChangeService.java

@@ -69,4 +69,6 @@ public interface StoreMngChangeService {
      * @return 删除条数
      */
     int deleteBatch(Integer[] ids);
+
+    void saveBatch(List<StoreMngChangeEntity> mngChangeEntityList);
 }

+ 86 - 0
kmall-admin/src/main/java/com/kmall/admin/service/haikong/StockChangeRecordService.java

@@ -0,0 +1,86 @@
+package com.kmall.admin.service.haikong;
+
+
+import com.kmall.admin.dto.StockChangeRecordDto;
+import com.kmall.admin.entity.haikong.StockChangeRecordEntity;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 海控出入库单记录Service接口
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2021-12-27 16:21:47
+ */
+public interface StockChangeRecordService {
+
+    /**
+     * 根据主键查询实体
+     *
+     * @param id 主键
+     * @return 实体
+     */
+    StockChangeRecordEntity queryObject(Integer id);
+
+    /**
+     * 分页查询
+     *
+     * @param map 参数
+     * @return list
+     */
+    List<StockChangeRecordEntity> queryList(Map<String, Object> map);
+
+    /**
+     * 分页统计总数
+     *
+     * @param map 参数
+     * @return 总数
+     */
+    int queryTotal(Map<String, Object> map);
+
+    /**
+     * 保存实体,修改库存
+     *
+     * @param stockChangeRecord 实体
+     * @return 保存条数
+     */
+    int save(StockChangeRecordEntity stockChangeRecord);
+
+    /**
+     * 根据主键更新实体,修改库存
+     *
+     * @param stockChangeRecord 实体
+     * @return 更新条数
+     */
+    int update(StockChangeRecordEntity stockChangeRecord);
+
+    /**
+     * 根据主键删除
+     *
+     * @param id
+     * @return 删除条数
+     */
+    int delete(Integer id);
+
+    /**
+     * 根据主键批量删除
+     *
+     * @param ids
+     * @return 删除条数
+     */
+    int deleteBatch(Integer[]ids);
+
+    void uploadExcel(List<StockChangeRecordDto> stockChangeRecordDtos);
+
+    /**
+     * 导入,需要修改库存
+     */
+    void saveBatch(List<StockChangeRecordEntity> stockChangeRecordEntities);
+
+    /**
+     * 订单提交时进行保存,不修改库存
+     */
+    void saveBatchByOrderSubmit(List<StockChangeRecordEntity> stockChangeRecordEntities);
+}

+ 81 - 1
kmall-admin/src/main/java/com/kmall/admin/service/impl/GoodsServiceImpl.java

@@ -10,6 +10,7 @@ import com.kmall.admin.dto.GoodsDetailsDto;
 import com.kmall.admin.dto.GoodsDto;
 import com.kmall.admin.dto.GoodsPanoramaDto;
 import com.kmall.admin.entity.*;
+import com.kmall.admin.entity.haikong.StockChangeRecordEntity;
 import com.kmall.admin.entity.kmall2eccs.KtoEccsEntity;
 import com.kmall.admin.entity.mk.MkActivitiesEntity;
 import com.kmall.admin.entity.shop.ShopErrorPriceRecordEntity;
@@ -131,6 +132,8 @@ public class GoodsServiceImpl implements GoodsService {
     private MkActivitiesHalfPriceService halfPriceService; // 第二份半价
     @Autowired
     private BrandService brandService;
+    @Autowired
+    private MngChangeService mngChangeService;
 
     @Autowired
     private ShopErrorPriceRecordService shopErrorPriceRecordService;
@@ -165,6 +168,12 @@ public class GoodsServiceImpl implements GoodsService {
         GoodsEntity entity = goodsDao.queryObjectByProdBarcodeAndBizType(prodBarcode, storeId);
         return entity;
     }
+
+    @Override
+    public GoodsEntity queryObjectByProdBarcodeAndStoreId(String prodBarcode, Integer storeId) {
+        return goodsDao.queryObjectByProdBarcodeAndStoreId(prodBarcode, storeId);
+    }
+
     @Override
     public List<GoodsEntity> queryList(Map<String, Object> map) {
         return goodsDao.queryList(map);
@@ -902,7 +911,8 @@ public class GoodsServiceImpl implements GoodsService {
                 }
                  GoodsEntity goodsNew = goodsDao.queryObjectBySnNew(goodsDto.getGoodsSn());
                  if(goodsNew!=null){
-                     throw new RRException("该商品数据已存在,请勿重复导入:"+goodsNew.getGoodsSn());
+                     goodsDao.update(goodsNew);
+//                     throw new RRException("该商品数据已存在,请勿重复导入:"+goodsNew.getGoodsSn());
                  }
                 // 获取品牌唯一简码
                 checkBrand(goodsDto, goodsEntity);
@@ -2141,4 +2151,74 @@ public class GoodsServiceImpl implements GoodsService {
     public int updateStockNumberByProductCodeAndSku(GoodsEntity goodsEntity) {
         return goodsDao.updateStockNumberByProductCodeAndSku(goodsEntity);
     }
+
+    /**
+     * 出库单更新库存(扣减)
+     *
+     * @param outboundList 出库sku
+     */
+    @Override
+    public void updateStockNumberByOutbound(List<StockChangeRecordEntity> outboundList) {
+
+        List<MngChangeEntity> changeEntityList = outboundList.stream().map(entity -> {
+            MngChangeEntity mngChangeEntity = new MngChangeEntity();
+            SysUserEntity user = ShiroUtils.getUserEntity();
+            Date date = new Date();
+            Integer number = entity.getNumber();
+            GoodsEntity goodsEntity = queryByBarcode(entity.getSku());
+
+            mngChangeEntity.setChangeType(Dict.changeType.item_5.getItem());
+            mngChangeEntity.setGoodsId(goodsEntity.getId().intValue());
+            mngChangeEntity.setChangeNum(number);
+            mngChangeEntity.setOriginalNum(goodsEntity.getGoodsNumber());
+            mngChangeEntity.setValidNum(goodsEntity.getGoodsNumber() - number);
+            mngChangeEntity.setChangeReason(Dict.changeType.item_5.getItemName());
+            mngChangeEntity.setCreateTime(date);
+            mngChangeEntity.setModTime(date);
+            mngChangeEntity.setCreaterSn(user.getUsername());
+            mngChangeEntity.setModerSn(user.getUsername());
+            mngChangeEntity.setIsValid(0);
+            mngChangeEntity.setMerchSn(goodsEntity.getMerchSn());
+            mngChangeEntity.setThirdPartyMerchCode(goodsEntity.getThirdPartyMerchCode());
+
+            return mngChangeEntity;
+        }).collect(Collectors.toList());
+        mngChangeService.saveBatch(changeEntityList);
+        goodsDao.updateStockNumberByOutbound(outboundList);
+    }
+
+    /**
+     * 入库单更新库存(增加)
+     *
+     * @param storageList 入库sku
+     */
+    @Override
+    public void updateStockNumberByStorage(List<StockChangeRecordEntity> storageList) {
+
+        List<MngChangeEntity> changeEntityList = storageList.stream().map(entity -> {
+            MngChangeEntity mngChangeEntity = new MngChangeEntity();
+            SysUserEntity user = ShiroUtils.getUserEntity();
+            Date date = new Date();
+            Integer number = entity.getNumber();
+            GoodsEntity goodsEntity = queryByBarcode(entity.getSku());
+
+            mngChangeEntity.setChangeType(Dict.changeType.item_6.getItem());
+            mngChangeEntity.setGoodsId(goodsEntity.getId().intValue());
+            mngChangeEntity.setChangeNum(number);
+            mngChangeEntity.setOriginalNum(goodsEntity.getGoodsNumber());
+            mngChangeEntity.setValidNum(goodsEntity.getGoodsNumber() + number);
+            mngChangeEntity.setChangeReason(Dict.changeType.item_6.getItemName());
+            mngChangeEntity.setCreateTime(date);
+            mngChangeEntity.setModTime(date);
+            mngChangeEntity.setCreaterSn(user.getUsername());
+            mngChangeEntity.setModerSn(user.getUsername());
+            mngChangeEntity.setIsValid(0);
+            mngChangeEntity.setMerchSn(goodsEntity.getMerchSn());
+            mngChangeEntity.setThirdPartyMerchCode(goodsEntity.getThirdPartyMerchCode());
+
+            return mngChangeEntity;
+        }).collect(Collectors.toList());
+        mngChangeService.saveBatch(changeEntityList);
+        goodsDao.updateStockNumberByStorage(storageList);
+    }
 }

+ 5 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/MngChangeServiceImpl.java

@@ -55,4 +55,9 @@ public class MngChangeServiceImpl implements MngChangeService {
     public int deleteBatch(Integer[]ids) {
         return mngChangeDao.deleteBatch(ids);
     }
+
+    @Override
+    public void saveBatch(List<MngChangeEntity> changeEntityList) {
+        mngChangeDao.saveBatch(changeEntityList);
+    }
 }

+ 100 - 72
kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java

@@ -324,6 +324,9 @@ public class OrderServiceImpl implements OrderService {
     @Autowired
     private HaiKongSendOrderInfoDetailRecordService haiKongSendOrderInfoDetailRecordService;
 
+    @Autowired
+    private StockChangeRecordService stockChangeRecordService;
+
     @Override
     public OrderEntity queryObject(Long id) {
         return orderDao.queryObject(id);
@@ -2177,13 +2180,16 @@ public class OrderServiceImpl implements OrderService {
         List<QueryGoodsVO> queryGoodsVOList = new ArrayList<>();
         Map<String, GoodsEntity> goodsEntityMap;
         List<GoodsEntity> goodsEntityList;
+
+        List<StockChangeRecordEntity> stockChangeRecordEntities = new ArrayList<>();
         try {
             goodsList.forEach(map -> {
                 QueryGoodsVO queryGoodsVo = new QueryGoodsVO();
                 queryGoodsVo.setProdBarcode((String) map.get("prodBarcode"));
                 queryGoodsVo.setSku((String) map.get("goodsSn"));
                 queryGoodsVo.setStoreId(storeId.longValue());
-                queryGoodsVo.setSellVolume((Integer) map.get("sellVolume"));
+                Integer sellVolume = (Integer) map.get("sellVolume");
+                queryGoodsVo.setSellVolume(sellVolume);
                 queryGoodsVo.setRetailPrice(new BigDecimal(String.valueOf(map.get("retailPrice"))));
                 queryGoodsVo.setGoodsTaxes(new BigDecimal(String.valueOf(map.get("goodstaxes"))));
                 Object discountedPriceObj = map.get("discountedPrice");
@@ -2206,6 +2212,17 @@ public class OrderServiceImpl implements OrderService {
                     deductionPrice = new BigDecimal(deductionPriceObj.toString());
                 }
                 queryGoodsVo.setDeductionPrice(deductionPrice);
+
+                StockChangeRecordEntity stockChangeRecordEntity = new StockChangeRecordEntity();
+                stockChangeRecordEntity.setNumber(sellVolume);
+                stockChangeRecordEntity.setMerchSn(user.getMerchSn());
+                stockChangeRecordEntity.setThirdMerchSn(user.getThirdPartyMerchCode());
+                stockChangeRecordEntity.setRemark("销售出库");
+                stockChangeRecordEntity.setSku(queryGoodsVo.getProdBarcode());
+                stockChangeRecordEntity.setStoreId(storeId);
+                stockChangeRecordEntity.setType(Constants.StockChangeType.item_2.getType());
+                stockChangeRecordEntities.add(stockChangeRecordEntity);
+
                 queryGoodsVOList.add(queryGoodsVo);
             });
             // 将在循环中查询数据库改为一次性查询
@@ -2216,6 +2233,8 @@ public class OrderServiceImpl implements OrderService {
             throw new ServiceException(e);
         }
 
+
+
         Map resultObj = Maps.newHashMap();
         // 海控需求,下单流程修改,收银端接收会员码,付款码,用户信息,订单数据
         // 1. 校验库存:保税仓库存 + 展销店库存 - 出区数 >= 购买数
@@ -2310,8 +2329,6 @@ public class OrderServiceImpl implements OrderService {
             listUtils.copyList(goodsEntityList, queryGoodsVOList);
 
             //生成商户订单号
-            SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
-//            String orderSn = "ZMHK" + format.format(new Date()) + CommonUtil.generateOrderNumber();
             Snowflake snowflake = IdUtil.createSnowflake(14, 14);
             String orderSn = "8" + snowflake.nextIdStr().substring(6);
             // 检查库存和更新库存
@@ -2526,6 +2543,12 @@ public class OrderServiceImpl implements OrderService {
             // 批量保存订单详情
             orderGoodsService.saveBatchOrderDetail(orderGoodsVoList);
 
+            stockChangeRecordEntities.forEach(stockChangeRecordEntity -> {
+                stockChangeRecordEntity.setOrderSn(orderSn);
+            });
+
+            stockChangeRecordService.saveBatchByOrderSubmit(stockChangeRecordEntities);
+
             //清空预订单商品临时表
             Map orderInfoMap = Maps.newHashMap();
             orderInfoMap.put("orderInfo", order);
@@ -2633,9 +2656,10 @@ public class OrderServiceImpl implements OrderService {
                             orderGiftScoreRulesVo.setGenerateType(Constants.MemberScoreRulesEnum.TWO.getCode());
                             if (ratio.compareTo(BigDecimal.ZERO) > 0) {
                                 // 算出所积的分
-                                int giftScore = money.multiply(ratio).setScale(0, BigDecimal.ROUND_FLOOR).add(new BigDecimal(memberScore.get())).intValue();
+                                BigDecimal bigDecimal = money.multiply(ratio).setScale(0, BigDecimal.ROUND_FLOOR);
+                                int giftScore = bigDecimal.add(new BigDecimal(memberScore.get())).intValue();
                                 memberScore.set(giftScore);
-                                orderGiftScoreRulesVo.setGiftScore(giftScore);
+                                orderGiftScoreRulesVo.setGiftScore(bigDecimal.intValue());
                                 orderGiftScoreRulesVo.setGenerateRatio(ratio);
                             } else {
                                 // 积分比例设置为0,该商品不记积分。
@@ -2663,9 +2687,10 @@ public class OrderServiceImpl implements OrderService {
                                     BigDecimal money = goodsMap.get(sku);
                                     if (ratio.compareTo(BigDecimal.ZERO) > 0) {
                                         // 算出所积的分
-                                        int giftScore = money.multiply(ratio).setScale(0, BigDecimal.ROUND_FLOOR).add(new BigDecimal(memberScore.get())).intValue();
+                                        BigDecimal bigDecimal = money.multiply(ratio).setScale(0, BigDecimal.ROUND_FLOOR);
+                                        int giftScore = bigDecimal.add(new BigDecimal(memberScore.get())).intValue();
                                         memberScore.set(giftScore);
-                                        orderGiftScoreRulesVo.setGiftScore(giftScore);
+                                        orderGiftScoreRulesVo.setGiftScore(bigDecimal.intValue());
                                         orderGiftScoreRulesVo.setGenerateRatio(ratio);
                                     } else {
                                         // 积分比例设置为0,该商品不记积分。
@@ -2692,9 +2717,10 @@ public class OrderServiceImpl implements OrderService {
                                 BigDecimal money = goodsMap.get(sku);
                                 if (ratio.compareTo(BigDecimal.ZERO) != 0) {
                                     // 算出所积的分
-                                    int giftScore = money.multiply(ratio).setScale(0, BigDecimal.ROUND_FLOOR).add(new BigDecimal(memberScore.get())).intValue();
+                                    BigDecimal bigDecimal = money.multiply(ratio).setScale(0, BigDecimal.ROUND_FLOOR);
+                                    int giftScore = bigDecimal.add(new BigDecimal(memberScore.get())).intValue();
                                     memberScore.set(giftScore);
-                                    orderGiftScoreRulesVo.setGiftScore(giftScore);
+                                    orderGiftScoreRulesVo.setGiftScore(bigDecimal.intValue());
                                     orderGiftScoreRulesVo.setGenerateRatio(ratio);
                                 } else {
                                     // 积分比例设置为0,该商品不记积分。
@@ -4643,73 +4669,75 @@ public class OrderServiceImpl implements OrderService {
 
         // 根据收银端开关选择是否适用积分抵扣。
         boolean useScore = Objects.isNull(calculateOrderDiscountPriceVo.getUseScore()) || calculateOrderDiscountPriceVo.getUseScore();
-        if (useScore) {
-            // 计算完活动优惠后,计算积分抵扣。(活动与积分抵扣不互斥)
-            if (!org.springframework.util.StringUtils.isEmpty(memberCode)) {
-                String memberInfoByCodeResponseJson;
-                Response<Object> response;
-                try {
-                    // 查询会员信息
-                    if (memberCode.trim().length() == 11) {
-                        memberInfoByCodeResponseJson = haiKongMemberTemplate.getMemberInfoByPhone("{\"phone\":\"" + memberCode + "\"}");
-                    } else {
-                        memberInfoByCodeResponseJson = haiKongMemberTemplate.getMemberInfoByCode("{\"code\":\"" + memberCode + "\"}");
-                    }
-                    response = JacksonUtil.fromListJson(memberInfoByCodeResponseJson, new TypeReference<Response<Object>>() {
-                    });
-                    if (Objects.isNull(response)) {
-                        LOGGER.error("请求会员系统出现异常!error:{}", memberInfoByCodeResponseJson);
-                        if (ErrorCodeConstants.MemberSysErrorCodeEnum.CODE_401.getCode().equals(response.getCode())) {
-                            JedisUtil.del(Constants.MEMBER_SYS_ACCESS_TOKEN_REDIS_KEY);
-                            throw new ServiceException(String.format("请求会员系统出现异常!会员码:%s,error:%s", memberCode, ErrorCodeConstants.MemberSysErrorCodeEnum.CODE_401.getDesc()));
-                        }
-                        throw new ServiceException(String.format("请求会员系统出现异常!会员码:%s,error:%s", memberCode, memberInfoByCodeResponseJson));
-                    }
-                } catch (Exception e) {
-                    LOGGER.error("请求会员系统失败或处理响应失败!", e);
-                    throw new ServiceException(e);
+        // 计算完活动优惠后,计算积分抵扣。(活动与积分抵扣不互斥)
+        if (!org.springframework.util.StringUtils.isEmpty(memberCode)) {
+            String memberInfoByCodeResponseJson;
+            Response<Object> response;
+            try {
+                // 查询会员信息
+                if (memberCode.trim().length() == 11) {
+                    memberInfoByCodeResponseJson = haiKongMemberTemplate.getMemberInfoByPhone("{\"phone\":\"" + memberCode + "\"}");
+                } else {
+                    memberInfoByCodeResponseJson = haiKongMemberTemplate.getMemberInfoByCode("{\"code\":\"" + memberCode + "\"}");
                 }
-                BigDecimal afterDiscountPrice;
-                if (response.getSuccess()) {
-                    MemberInfoDTO memberInfoDTO = JacksonUtil.fromStringJson(JacksonUtil.toJson(response.getData()), MemberInfoDTO.class);
-                    assert memberInfoDTO != null : String.format("会员码:【%s】会员信息错误!%s", memberCode, JacksonUtil.toJson(response));
-                    // 查询会员表
-                    calculateOrderDiscountPriceResponseVO.setOpenId(memberInfoDTO.getOpenId());
-                    calculateOrderDiscountPriceResponseVO.setMemberPhone(memberInfoDTO.getPhone());
-                    calculateOrderDiscountPriceResponseVO.setMemberCurrentAvailableScore(memberInfoDTO.getScore());
-                    calculateOrderDiscountPriceResponseVO.setLevelName(memberInfoDTO.getLevelName());
-                    UserEntity userEntity = userService.queryByOpenId(memberInfoDTO.getOpenId());
-                    String openId = memberInfoDTO.getOpenId();
-                    if (Objects.isNull(userEntity)) {
-                        userEntity = new UserEntity();
-                        userEntity.setOpenId(openId);
-                        userEntity.setMemberCode(memberCode);
-                        userEntity.setMobile(openId);
-                        userService.save(userEntity);
-                    } else {
-                        userEntity.setOpenId(openId);
-                        userEntity.setMobile(openId);
-                        userEntity.setMemberCode(memberCode);
-                        userService.update(userEntity);
-                    }
-                    Integer score = memberInfoDTO.getScore();
-                    if (Objects.nonNull(score) && score > 0) {
-                        // 有积分
-                        afterDiscountPrice = calculatePreferentialPrice(orderTotalPrice, score, memberCode, openId, calculateOrderDiscountPriceResponseVO, goodsDetailsDtos, promotionSkuList, mkActivitiesEntityList);
-                        LOGGER.info("会员【{}】,当前积分:{},积分抵扣后的订单金额:{},积分抵扣前的订单金额:{}", openId, score, afterDiscountPrice, orderTotalPrice);
-                        calculateOrderDiscountPriceResponseVO.setOrderTotalPrice(afterDiscountPrice);
-                        calculateOrderDiscountPriceResponseVO.setGoodsDetailsDtos(goodsDetailsDtos);
-                        calculateOrderDiscountPriceResponseVO.setBeforeScore(score);
-                        // 订单完成后再添加积分消费记录,以及同步积分信息
-                        return calculateOrderDiscountPriceResponseVO;
-                    } else {
-                        LOGGER.error("会员【{}】积分为0,积分抵扣失败!", openId);
-                        return calculateOrderDiscountPriceResponseVO;
+                response = JacksonUtil.fromListJson(memberInfoByCodeResponseJson, new TypeReference<Response<Object>>() {
+                });
+                if (Objects.isNull(response)) {
+                    LOGGER.error("请求会员系统出现异常!error:{}", memberInfoByCodeResponseJson);
+                    if (ErrorCodeConstants.MemberSysErrorCodeEnum.CODE_401.getCode().equals(response.getCode())) {
+                        JedisUtil.del(Constants.MEMBER_SYS_ACCESS_TOKEN_REDIS_KEY);
+                        throw new ServiceException(String.format("请求会员系统出现异常!会员码:%s,error:%s", memberCode, ErrorCodeConstants.MemberSysErrorCodeEnum.CODE_401.getDesc()));
                     }
+                    throw new ServiceException(String.format("请求会员系统出现异常!会员码:%s,error:%s", memberCode, memberInfoByCodeResponseJson));
+                }
+            } catch (Exception e) {
+                LOGGER.error("请求会员系统失败或处理响应失败!", e);
+                throw new ServiceException(e);
+            }
+            BigDecimal afterDiscountPrice;
+            if (response.getSuccess()) {
+                MemberInfoDTO memberInfoDTO = JacksonUtil.fromStringJson(JacksonUtil.toJson(response.getData()), MemberInfoDTO.class);
+                assert memberInfoDTO != null : String.format("会员码:【%s】会员信息错误!%s", memberCode, JacksonUtil.toJson(response));
+                // 查询会员表
+                calculateOrderDiscountPriceResponseVO.setOpenId(memberInfoDTO.getOpenId());
+                calculateOrderDiscountPriceResponseVO.setMemberPhone(memberInfoDTO.getPhone());
+                calculateOrderDiscountPriceResponseVO.setMemberCurrentAvailableScore(memberInfoDTO.getScore());
+                calculateOrderDiscountPriceResponseVO.setLevelName(memberInfoDTO.getLevelName());
+                UserEntity userEntity = userService.queryByOpenId(memberInfoDTO.getOpenId());
+                String openId = memberInfoDTO.getOpenId();
+                if (Objects.isNull(userEntity)) {
+                    userEntity = new UserEntity();
+                    userEntity.setOpenId(openId);
+                    userEntity.setMemberCode(memberCode);
+                    userEntity.setMobile(openId);
+                    userService.save(userEntity);
                 } else {
-                    LOGGER.error("查询会员信息失败!响应结果:{}", memberInfoByCodeResponseJson);
-                    throw new ServiceException(String.format("会员码:%s,错误码:%s,错误信息:%s", memberCode, response.getErrorCode(), response.getErrorMessage()));
+                    userEntity.setOpenId(openId);
+                    userEntity.setMobile(openId);
+                    userEntity.setMemberCode(memberCode);
+                    userService.update(userEntity);
+                }
+                Integer score = memberInfoDTO.getScore();
+                // 是否适用积分抵扣
+                if (!useScore) {
+                    return calculateOrderDiscountPriceResponseVO;
                 }
+                if (Objects.nonNull(score) && score > 0) {
+                    // 有积分
+                    afterDiscountPrice = calculatePreferentialPrice(orderTotalPrice, score, memberCode, openId, calculateOrderDiscountPriceResponseVO, goodsDetailsDtos, promotionSkuList, mkActivitiesEntityList);
+                    LOGGER.info("会员【{}】,当前积分:{},积分抵扣后的订单金额:{},积分抵扣前的订单金额:{}", openId, score, afterDiscountPrice, orderTotalPrice);
+                    calculateOrderDiscountPriceResponseVO.setOrderTotalPrice(afterDiscountPrice);
+                    calculateOrderDiscountPriceResponseVO.setGoodsDetailsDtos(goodsDetailsDtos);
+                    calculateOrderDiscountPriceResponseVO.setBeforeScore(score);
+                    // 订单完成后再添加积分消费记录,以及同步积分信息
+                    return calculateOrderDiscountPriceResponseVO;
+                } else {
+                    LOGGER.error("会员【{}】积分为0,积分抵扣失败!", openId);
+                    return calculateOrderDiscountPriceResponseVO;
+                }
+            } else {
+                LOGGER.error("查询会员信息失败!响应结果:{}", memberInfoByCodeResponseJson);
+                throw new ServiceException(String.format("会员码:%s,错误码:%s,错误信息:%s", memberCode, response.getErrorCode(), response.getErrorMessage()));
             }
         }
         calculateOrderDiscountPriceResponseVO.setGoodsDetailsDtos(goodsDetailsDtos);

+ 80 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/ProductStoreRelaServiceImpl.java

@@ -6,10 +6,13 @@ import com.kmall.admin.dao.*;
 import com.kmall.admin.dao.mk.dist.MkDistSellAllocationDao;
 import com.kmall.admin.dto.StoreGoodsDto;
 import com.kmall.admin.entity.*;
+import com.kmall.admin.entity.haikong.StockChangeRecordEntity;
 import com.kmall.admin.entity.mk.dist.MkDistSellAllocationEntity;
 import com.kmall.admin.fromcomm.entity.SysUserEntity;
 import com.kmall.admin.service.BrandService;
+import com.kmall.admin.service.GoodsService;
 import com.kmall.admin.service.ProductStoreRelaService;
+import com.kmall.admin.service.StoreMngChangeService;
 import com.kmall.admin.service.kmall2eccs.KtoEccsService;
 import com.kmall.admin.utils.ShiroUtils;
 import com.kmall.api.util.StockUtil;
@@ -23,6 +26,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * Service实现类
@@ -75,6 +79,12 @@ public class ProductStoreRelaServiceImpl implements ProductStoreRelaService {
     private GoodsBatchDao goodsBatchDao;
 
     @Autowired
+    private StoreMngChangeService storeMngChangeService;
+
+    @Autowired
+    private GoodsService goodsService;
+
+    @Autowired
     private KtoEccsService ktoEccsService;
 
     @Override
@@ -1166,4 +1176,74 @@ public class ProductStoreRelaServiceImpl implements ProductStoreRelaService {
     public void updateStockNumByStoreIdAndSku(ProductStoreRelaEntity productStoreRelaEntity) {
         productStoreRelaDao.updateStockNumByStoreIdAndSku(productStoreRelaEntity);
     }
+
+    /**
+     * 出库单更新库存(扣减)
+     *
+     * @param outboundList 出库sku
+     */
+    @Override
+    public void updateStockNumberByOutbound(List<StockChangeRecordEntity> outboundList) {
+        List<StoreMngChangeEntity> mngChangeEntityList = outboundList.stream().map(entity -> {
+            StoreMngChangeEntity storeMngChangeEntity = new StoreMngChangeEntity();
+            String sku = entity.getSku();
+            Integer number = entity.getNumber();
+            Integer storeId = entity.getStoreId();
+            Date date = new Date();
+            SysUserEntity userEntity = ShiroUtils.getUserEntity();
+            GoodsEntity goodsEntity = goodsService.queryObjectByProdBarcodeAndStoreId(sku, storeId);
+            storeMngChangeEntity.setChangeReason("出库单");
+            storeMngChangeEntity.setChangeType(Dict.changeType.item_5.getItem());
+            storeMngChangeEntity.setStoreChangeNum(number);
+            storeMngChangeEntity.setGoodsId(goodsEntity.getId().intValue());
+            storeMngChangeEntity.setGoodsName(sku);
+            storeMngChangeEntity.setStoreId(storeId);
+            storeMngChangeEntity.setStoreOriginalNum(goodsEntity.getStockNum());
+            storeMngChangeEntity.setStoreName(goodsEntity.getStoreName());
+            storeMngChangeEntity.setStoreValidNum(goodsEntity.getStockNum() - number);
+            storeMngChangeEntity.setIsValid(0);
+            storeMngChangeEntity.setModTime(date);
+            storeMngChangeEntity.setCreateTime(date);
+            storeMngChangeEntity.setCreaterSn(userEntity.getUsername());
+            storeMngChangeEntity.setModerSn(userEntity.getUsername());
+            return storeMngChangeEntity;
+        }).collect(Collectors.toList());
+        storeMngChangeService.saveBatch(mngChangeEntityList);
+        productStoreRelaDao.updateStockNumberByOutbound(outboundList);
+    }
+
+    /**
+     * 入库单更新库存(增加)
+     *
+     * @param storageList 入库sku
+     */
+    @Override
+    public void updateStockNumberByStorage(List<StockChangeRecordEntity> storageList) {
+        List<StoreMngChangeEntity> mngChangeEntityList = storageList.stream().map(entity -> {
+            StoreMngChangeEntity storeMngChangeEntity = new StoreMngChangeEntity();
+            String sku = entity.getSku();
+            Integer number = entity.getNumber();
+            Integer storeId = entity.getStoreId();
+            Date date = new Date();
+            SysUserEntity userEntity = ShiroUtils.getUserEntity();
+            GoodsEntity goodsEntity = goodsService.queryObjectByProdBarcodeAndStoreId(sku, storeId);
+            storeMngChangeEntity.setChangeReason("入库单");
+            storeMngChangeEntity.setChangeType(Dict.changeType.item_6.getItem());
+            storeMngChangeEntity.setStoreChangeNum(number);
+            storeMngChangeEntity.setGoodsId(goodsEntity.getId().intValue());
+            storeMngChangeEntity.setGoodsName(sku);
+            storeMngChangeEntity.setStoreId(storeId);
+            storeMngChangeEntity.setStoreOriginalNum(goodsEntity.getStockNum());
+            storeMngChangeEntity.setStoreName(goodsEntity.getStoreName());
+            storeMngChangeEntity.setStoreValidNum(goodsEntity.getStockNum() + number);
+            storeMngChangeEntity.setIsValid(0);
+            storeMngChangeEntity.setModTime(date);
+            storeMngChangeEntity.setCreateTime(date);
+            storeMngChangeEntity.setCreaterSn(userEntity.getUsername());
+            storeMngChangeEntity.setModerSn(userEntity.getUsername());
+            return storeMngChangeEntity;
+        }).collect(Collectors.toList());
+        storeMngChangeService.saveBatch(mngChangeEntityList);
+        productStoreRelaDao.updateStockNumberByStorage(storageList);
+    }
 }

+ 5 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/StoreMngChangeServiceImpl.java

@@ -55,4 +55,9 @@ public class StoreMngChangeServiceImpl implements StoreMngChangeService {
     public int deleteBatch(Integer[]ids) {
         return storeMngChangeDao.deleteBatch(ids);
     }
+
+    @Override
+    public void saveBatch(List<StoreMngChangeEntity> mngChangeEntityList) {
+        storeMngChangeDao.saveBatch(mngChangeEntityList);
+    }
 }

+ 177 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/haikong/StockChangeRecordServiceImpl.java

@@ -0,0 +1,177 @@
+package com.kmall.admin.service.impl.haikong;
+
+import com.google.common.collect.ImmutableBiMap;
+import com.kmall.admin.dao.haikong.StockChangeRecordDao;
+import com.kmall.admin.dto.StockChangeRecordDto;
+import com.kmall.admin.entity.GoodsEntity;
+import com.kmall.admin.entity.haikong.StockChangeRecordEntity;
+import com.kmall.admin.haikong.constant.Constants;
+import com.kmall.admin.service.GoodsService;
+import com.kmall.admin.service.ProductStoreRelaService;
+import com.kmall.admin.service.haikong.StockChangeRecordService;
+import com.kmall.common.constant.Dict;
+import com.kmall.common.utils.MapBeanUtil;
+import com.kmall.common.utils.R;
+import com.kmall.common.utils.RRException;
+import com.kmall.common.utils.ValidatorUtil;
+import org.springframework.aop.framework.AopContext;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+
+
+/**
+ * 海控出入库单记录Service实现类
+ *
+ * @author emato
+ * @email admin@qhdswl.com
+ * @date 2021-12-27 16:21:47
+ */
+@Service("stockChangeRecordService")
+public class StockChangeRecordServiceImpl implements StockChangeRecordService {
+    @Autowired
+    private StockChangeRecordDao stockChangeRecordDao;
+
+    @Autowired
+    private GoodsService goodsService;
+
+    @Autowired
+    private ProductStoreRelaService productStoreRelaService;
+
+    @Override
+    public StockChangeRecordEntity queryObject(Integer id) {
+        return stockChangeRecordDao.queryObject(id);
+    }
+
+    @Override
+    public List<StockChangeRecordEntity> queryList(Map<String, Object> map) {
+        return stockChangeRecordDao.queryList(map);
+    }
+
+    @Override
+    public int queryTotal(Map<String, Object> map) {
+        return stockChangeRecordDao.queryTotal(map);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public synchronized int save(StockChangeRecordEntity stockChangeRecord) {
+        Date modifyTime = new Date();
+        stockChangeRecord.setModifyTime(modifyTime);
+        stockChangeRecord.setCreateTime(modifyTime);
+
+        List<StockChangeRecordEntity> storageList = Collections.singletonList(stockChangeRecord);
+        if (Constants.StockChangeType.item_0.getType().equals(stockChangeRecord.getType())) {
+            // 出库
+            productStoreRelaService.updateStockNumberByOutbound(storageList);
+            goodsService.updateStockNumberByOutbound(storageList);
+        } else if (Constants.StockChangeType.item_1.getType().equals(stockChangeRecord.getType())) {
+            // 入库
+            productStoreRelaService.updateStockNumberByStorage(storageList);
+            goodsService.updateStockNumberByStorage(storageList);
+        }
+
+        return stockChangeRecordDao.save(stockChangeRecord);
+    }
+
+    @Override
+    public int update(StockChangeRecordEntity stockChangeRecord) {
+        stockChangeRecord.setModifyTime(new Date());
+        return stockChangeRecordDao.update(stockChangeRecord);
+    }
+
+    @Override
+    public int delete(Integer id) {
+        return stockChangeRecordDao.delete(id);
+    }
+
+    @Override
+    public int deleteBatch(Integer[]ids) {
+        return stockChangeRecordDao.deleteBatch(ids);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void uploadExcel(List<StockChangeRecordDto> stockChangeRecordDtos) {
+        if (!CollectionUtils.isEmpty(stockChangeRecordDtos)) {
+            List<StockChangeRecordEntity> stockChangeRecordEntities = new ArrayList<>();
+
+            stockChangeRecordDtos.forEach(stockChangeRecordDto -> {
+                Map<String, Object> valideDate = MapBeanUtil.fromObject(stockChangeRecordDto);
+                // 校验excel传入的数据
+                ImmutableBiMap.Builder builder = new ImmutableBiMap.Builder();
+                builder.put("storeId", "门店编号");
+                builder.put("merchSn", "商户编号");
+                builder.put("thirdMerchSn", "第三方商户编号");
+                builder.put("sku", "商品SKU");
+                builder.put("type", "出入库类型");
+                builder.put("number", "出入库数量");
+
+                R r = ValidatorUtil.isEmpty(builder.build(), valideDate);
+                if (Integer.valueOf(r.get("code").toString()) != 0) {
+                    throw new RRException(r.get("msg").toString());
+                }
+
+                StockChangeRecordEntity stockChangeRecordEntity = new StockChangeRecordEntity();
+                BeanUtils.copyProperties(stockChangeRecordDto, stockChangeRecordEntity);
+                Date createTime = new Date();
+                stockChangeRecordEntity.setCreateTime(createTime);
+                stockChangeRecordEntity.setModifyTime(createTime);
+                stockChangeRecordEntities.add(stockChangeRecordEntity);
+            });
+
+            ((StockChangeRecordService) AopContext.currentProxy()).saveBatch(stockChangeRecordEntities);
+
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public synchronized void saveBatch(List<StockChangeRecordEntity> stockChangeRecordEntities) {
+
+        Map<String, List<StockChangeRecordEntity>> stringListHashMap = new HashMap<>();
+
+        stockChangeRecordEntities.forEach(entity -> {
+            String type = entity.getType();
+            if (stringListHashMap.containsKey(type)) {
+                List<StockChangeRecordEntity> entities = stringListHashMap.get(type);
+                entities.add(entity);
+                stringListHashMap.put(type, entities);
+            } else {
+                ArrayList<StockChangeRecordEntity> entities = new ArrayList<>();
+                entities.add(entity);
+                stringListHashMap.put(type, entities);
+            }
+        });
+
+        // 出库和入库,需要修改库存
+        // 出库集合,减库存
+        List<StockChangeRecordEntity> outboundList = stringListHashMap.get(Constants.StockChangeType.item_0.getType());
+        if (!CollectionUtils.isEmpty(outboundList)) {
+            productStoreRelaService.updateStockNumberByOutbound(outboundList);
+            goodsService.updateStockNumberByOutbound(outboundList);
+        }
+        // 入库集合,加库存
+        List<StockChangeRecordEntity> storageList = stringListHashMap.get(Constants.StockChangeType.item_1.getType());
+        if (!CollectionUtils.isEmpty(storageList)) {
+            productStoreRelaService.updateStockNumberByStorage(storageList);
+            goodsService.updateStockNumberByStorage(storageList);
+        }
+
+        stockChangeRecordDao.saveBatch(stockChangeRecordEntities);
+    }
+
+    /**
+     * 订单提交时进行保存,不修改库存
+     *
+     */
+    @Override
+    public void saveBatchByOrderSubmit(List<StockChangeRecordEntity> stockChangeRecordEntities) {
+        stockChangeRecordDao.saveBatch(stockChangeRecordEntities);
+    }
+
+}

+ 23 - 0
kmall-admin/src/main/resources/XmlTemplate/StockChangeRecordDtoList.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<workbook>
+    <worksheet name="Sheet1">
+        <section startRow="0" endRow="0"/>
+        <loop startRow="1" endRow="1" items="StockChangeRecordDtoList" var="StockChangeRecordDto"
+              varType="com.kmall.admin.dto.StockChangeRecordDto">
+            <section startRow="1" endRow="1">
+                <mapping row="1" col="0">StockChangeRecordDto.merchSn</mapping>
+                <mapping row="1" col="1">StockChangeRecordDto.thirdMerchSn</mapping>
+                <mapping row="1" col="2">StockChangeRecordDto.storeId</mapping>
+                <mapping row="1" col="3">StockChangeRecordDto.sku</mapping>
+                <mapping row="1" col="4">StockChangeRecordDto.type</mapping>
+                <mapping row="1" col="5">StockChangeRecordDto.number</mapping>
+                <mapping row="1" col="6">StockChangeRecordDto.remark</mapping>
+            </section>
+            <loopbreakcondition>
+                <rowcheck offset="0">
+                    <cellcheck offset="0"></cellcheck>
+                </rowcheck>
+            </loopbreakcondition>
+        </loop>
+    </worksheet>
+</workbook>

+ 2 - 2
kmall-admin/src/main/resources/logback.xml

@@ -6,8 +6,8 @@ debug:当此属性设置为true时,将打印出logback内部日志信息,
 -->
 <configuration scan="false" scanPeriod="60 seconds" debug="false">
 
-<!--    <property name="LOG_HOME" value="/data/project/logs/kmall-haikong/kmall-admin/"/>-->
-    <property name="LOG_HOME" value="/app/project/logs/kmall-haikong/kmall-admin/"/>
+    <property name="LOG_HOME" value="/data/project/logs/kmall-haikong/kmall-admin/"/>
+<!--    <property name="LOG_HOME" value="/app/project/logs/kmall-haikong/kmall-admin/"/>-->
     <!-- 定义日志的根目录 -->
     <property name="TRACE_DIR" value="trace" />
     <property name="DEBUG_DIR" value="debug" />

+ 37 - 0
kmall-admin/src/main/resources/mybatis/mapper/GoodsDao.xml

@@ -221,6 +221,17 @@
         where a.is_delete=0 and a.prod_barcode = #{prodBarcode} and a.goods_biz_type = 11 and r.store_id = #{storeId}
     </select>
 
+    <select id="queryObjectByProdBarcodeAndStoreId" resultType="com.kmall.admin.entity.GoodsEntity">
+        SELECT
+            a.id,a.sku,a.goods_sn,a.name,a.list_pic_url,a.prod_barcode,r.market_price storeMarketPrice,r.retail_price storeRetailPrice ,r.stock_num,s.store_name,r.product_id,s.id 'storeId',
+            a.hs_code as hsCode , a.legal_unit1_qty as legalUnit1Qty , a.legal_unit2_qty as legalUnit2Qty,a.ciq_prod_model as ciqProdModel,a.to_be_restored
+        FROM
+            mall_goods a
+        LEFT JOIN mall_product_store_rela r ON r.goods_id = a.id
+        inner join mall_store s on r.store_id=s.id
+        where a.is_delete=0 and a.prod_barcode = #{prodBarcode} and r.store_id = #{storeId}
+    </select>
+
 
     <select id="queryObjectByProdBarcodeAndStore" resultType="com.kmall.admin.entity.GoodsEntity">
          SELECT
@@ -1152,6 +1163,32 @@
         where
         prod_barcode = #{prodBarcode} and sku = #{sku}
     </update>
+    <update id="updateStockNumberByOutbound">
+        update mall_goods
+        <trim prefix="set" suffixOverrides=",">
+            goods_number =
+            <foreach collection="list" item="item" open="case " close=" end,">
+                when sku = #{item.sku} then goods_number - #{item.number}
+            </foreach>
+        </trim>
+        where
+        <foreach collection="list" item="item" open="(" separator=") or (" close=")">
+            sku = #{item.sku}
+        </foreach>
+    </update>
+    <update id="updateStockNumberByStorage">
+        update mall_goods
+        <trim prefix="set" suffixOverrides=",">
+            goods_number =
+            <foreach collection="list" item="item" open="case " close=" end,">
+                when sku = #{item.sku} then goods_number + #{item.number}
+            </foreach>
+        </trim>
+        where
+        <foreach collection="list" item="item" open="(" separator=") or (" close=")">
+            sku = #{item.sku}
+        </foreach>
+    </update>
 
     <select id="syncOmsHsCodeGoode" resultType="java.lang.String">
         select sku from mall_goods where id in

+ 27 - 0
kmall-admin/src/main/resources/mybatis/mapper/ProductStoreRelaDao.xml

@@ -976,6 +976,33 @@
         </foreach>
     </update>
 
+    <update id="updateStockNumberByOutbound">
+        update mall_product_store_rela
+        <trim prefix="set" suffixOverrides=",">
+            stock_num =
+            <foreach collection="list" item="item" open="case " close=" end,">
+                when sku = #{item.sku} and store_id = #{item.storeId} then stock_num - #{item.number}
+            </foreach>
+        </trim>
+        where
+        <foreach collection="list" item="item" open="(" separator=") or (" close=")">
+            sku = #{item.sku} and store_id = #{item.storeId}
+        </foreach>
+    </update>
+    <update id="updateStockNumberByStorage">
+        update mall_product_store_rela
+        <trim prefix="set" suffixOverrides=",">
+            stock_num =
+            <foreach collection="list" item="item" open="case " close=" end,">
+                when sku = #{item.sku} and store_id = #{item.storeId} then stock_num + #{item.number}
+            </foreach>
+        </trim>
+        where
+        <foreach collection="list" item="item" open="(" separator=") or (" close=")">
+            sku = #{item.sku} and store_id = #{item.storeId}
+        </foreach>
+    </update>
+
 
     <select id="queryByGoodsIdAndStoreIdHkMall" resultType="com.kmall.admin.entity.ProductStoreRelaEntity">
         select

+ 40 - 0
kmall-admin/src/main/resources/mybatis/mapper/StoreMngChangeDao.xml

@@ -172,6 +172,46 @@
 			#{orderSn})
 	</insert>
 
+	<insert id="saveBatch" parameterType="com.kmall.admin.entity.StoreMngChangeEntity">
+		insert into mall_store_mng_change(
+			`store_change_num`,
+			`store_original_num`,
+			`store_valid_num`,
+			`merch_sn`,
+			`store_id`,
+			`goods_id`,
+			`is_valid`,
+			`change_type`,
+			`change_reason`,
+			`creater_sn`,
+			`create_time`,
+			`moder_sn`,
+			`mod_time`,
+			`tstm`,
+			order_sn)
+		values
+		<foreach collection="list" item="item" separator=",">
+			(
+				#{item.storeChangeNum},
+				#{item.storeOriginalNum},
+				#{item.storeValidNum},
+				#{item.merchSn},
+				#{item.storeId},
+				#{item.goodsId},
+				#{item.isValid},
+				#{item.changeType},
+				#{item.changeReason},
+				#{item.createrSn},
+				#{item.createTime},
+				#{item.moderSn},
+				#{item.modTime},
+				#{item.tstm},
+				#{item.orderSn}
+			)
+		</foreach>
+	</insert>
+
+
 	<update id="update" parameterType="com.kmall.admin.entity.StoreMngChangeEntity">
 		update mall_store_mng_change
 		<set>

+ 146 - 0
kmall-admin/src/main/resources/mybatis/mapper/haikong/StockChangeRecordDao.xml

@@ -0,0 +1,146 @@
+<?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.admin.dao.haikong.StockChangeRecordDao">
+
+    <resultMap type="com.kmall.admin.entity.haikong.StockChangeRecordEntity" id="stockChangeRecordMap">
+        <result property="id" column="id"/>
+        <result property="merchSn" column="merch_sn"/>
+        <result property="thirdMerchSn" column="third_merch_sn"/>
+        <result property="storeId" column="store_id"/>
+        <result property="sku" column="sku"/>
+        <result property="type" column="type"/>
+        <result property="number" column="number"/>
+        <result property="remark" column="remark"/>
+        <result property="orderSn" column="order_sn"/>
+        <result property="createTime" column="create_time"/>
+        <result property="modifyTime" column="modify_time"/>
+    </resultMap>
+
+	<select id="queryObject" resultMap="stockChangeRecordMap">
+		select
+			*
+		from mall_stock_change_record
+		where id = #{id}
+	</select>
+
+	<select id="queryList" resultMap="stockChangeRecordMap">
+		select
+    		*
+		from mall_stock_change_record
+		WHERE 1=1
+		<if test="type != null and type.trim() != ''">
+			AND `type` LIKE concat('%',#{type},'%')
+		</if>
+		<if test="sku != null and sku.trim() != ''">
+			AND `sku` LIKE concat('%',#{sku},'%')
+		</if>
+		<if test="storeId != null and storeId.trim() != ''">
+			AND `store_id` LIKE concat('%',#{storeId},'%')
+		</if>
+        <choose>
+            <when test="sidx != null and sidx.trim() != ''">
+                order by ${sidx} ${order}
+            </when>
+			<otherwise>
+                order by id desc
+			</otherwise>
+        </choose>
+		<if test="offset != null and limit != null">
+			limit #{offset}, #{limit}
+		</if>
+	</select>
+	
+ 	<select id="queryTotal" resultType="int">
+		select count(*) from mall_stock_change_record
+		WHERE 1=1
+        <if test="name != null and name.trim() != ''">
+            AND name LIKE concat('%',#{name},'%')
+        </if>
+	</select>
+	 
+	<insert id="save" parameterType="com.kmall.admin.entity.haikong.StockChangeRecordEntity" useGeneratedKeys="true" keyProperty="id">
+		insert into mall_stock_change_record(
+			`merch_sn`,
+			`third_merch_sn`,
+			`order_sn`,
+			`store_id`,
+			`sku`,
+			`type`,
+			`number`,
+			`remark`,
+			`create_time`,
+			`modify_time`)
+		values(
+			#{merchSn},
+			#{thirdMerchSn},
+			#{orderSn},
+			#{storeId},
+			#{sku},
+			#{type},
+			#{number},
+			#{remark},
+			#{createTime},
+			#{modifyTime})
+	</insert>
+
+	<insert id="saveBatch">
+		insert into mall_stock_change_record
+		(
+			`store_id`,
+			`merch_sn`,
+			`third_merch_sn`,
+			`order_sn`,
+			`sku`,
+			`type`,
+			`number`,
+			`remark`,
+			`create_time`,
+			`modify_time`
+		)
+		values
+		<foreach collection="list" item="item" separator=",">
+			(
+				#{item.storeId},
+				#{item.merchSn},
+				#{item.thirdMerchSn},
+				#{item.orderSn},
+				#{item.sku},
+				#{item.type},
+				#{item.number},
+				#{item.remark},
+				#{item.createTime},
+				#{item.modifyTime}
+			)
+		</foreach>
+	</insert>
+
+	<update id="update" parameterType="com.kmall.admin.entity.haikong.StockChangeRecordEntity">
+		update mall_stock_change_record 
+		<set>
+			<if test="storeId != null">`store_id` = #{storeId}, </if>
+			<if test="merchSn != null">`merch_sn` = #{merchSn}, </if>
+			<if test="thirdMerchSn != null">`third_merch_sn` = #{thirdMerchSn}, </if>
+			<if test="orderSn != null">`order_sn` = #{orderSn}, </if>
+			<if test="sku != null">`sku` = #{sku}, </if>
+			<if test="type != null">`type` = #{type}, </if>
+			<if test="number != null">`number` = #{number}, </if>
+			<if test="remark != null">`remark` = #{remark}, </if>
+			<if test="createTime != null">`create_time` = #{createTime}, </if>
+			<if test="modifyTime != null">`modify_time` = #{modifyTime}</if>
+		</set>
+		where id = #{id}
+	</update>
+	
+	<delete id="delete">
+		delete from mall_stock_change_record where id = #{value}
+	</delete>
+	
+	<delete id="deleteBatch">
+		delete from mall_stock_change_record where id in 
+		<foreach item="id" collection="array" open="(" separator="," close=")">
+			#{id}
+		</foreach>
+	</delete>
+
+</mapper>

+ 4 - 1
kmall-admin/src/main/webapp/WEB-INF/page/mk/mkactivitiespromotion.html

@@ -56,7 +56,10 @@
                 <i-input v-model="mkActivitiesPromotion.productBrand" placeholder="商品品牌"/>
             </Form-item>
             <Form-item label="是否参与积分抵扣" prop="rejectScore">
-                <i-input v-model="mkActivitiesPromotion.rejectScore" placeholder="是否参与积分抵扣,0:参与,1:不参与"/>
+                <i-select v-model="mkActivitiesPromotion.rejectScore" placeholder="是否参与积分抵扣,0:参与,1:不参与">
+                    <i-option value="0">参与</i-option>
+                    <i-option value="1">不参与</i-option>
+                </i-select>
             </Form-item>
             <Form-item label="商品系列" prop="productSeries">
                 <i-input v-model="mkActivitiesPromotion.productSeries" placeholder="商品系列"/>

+ 44 - 10
kmall-admin/src/main/webapp/WEB-INF/page/sale/sale.html

@@ -125,6 +125,7 @@
                                     <span style="margin-right: 40px">&nbsp; 门店:<b>{{storeName}}</b></span>
                                 </li>
                                 <li><span style="margin-right: 35px"><i class="fa fa-user-circle" ></i> &nbsp;收银员:<b>{{sysUserInfo.username}}</b></span></li>
+                                <li><a href="javascript:;" @click="updatePasswordOpen"><i class="fa fa-lock"></i> &nbsp;修改密码</a></li>
                                 <li><a @click="logout" style="font-size: 1em"><i class="fa fa fa-sign-out"></i> 退出</a></li>
                             </ul>
                         </Row>
@@ -298,7 +299,40 @@
                                         <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                                         <button type="button" class="btn btn-primary" @click="queryIDCardInfo">查询身份信息</button>
                                         <button type="button" class="btn btn-primary" @click="getIDCardInfo" id="IDCard">读取身份证信息</button>
-                                        <button type="button" class="btn btn-primary" @click="submitCustomInfo" id="Send">去付款</button>
+                                        <button type="button" class="btn btn-primary" @click="idCardVerification" id="Send" style="background-color:red;">去付款</button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="modal fade" id="updatePasswordDialog"  role="dialog" aria-hidden="true">
+                            <div class="modal-dialog">
+                                <div class="modal-content">
+                                    <div class="modal-header">
+                                        <button type="button" class="close" data-dismiss="modal" @click="closeUpdatePasswordDialog" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+                                        <h4 class="modal-title" id="updatePasswordLabel">修改密码</h4>
+                                    </div>
+                                    <div class="modal-body">
+                                        <div>
+                                            <label class="control-label">账号:</label>
+                                            <span class="label label-success" style="vertical-align: center;">{{sysUserInfo.username}}</span>
+                                        </div>
+                                        <div style="margin-top: 30px">
+                                            <label class="control-label" for="oldPassword">原密码:</label>
+                                            <input type="password" class="form-control" v-model="oldPassword" ref="oldPassword" size="40%" id="oldPassword" />
+                                        </div>
+                                        <div style="margin-top: 30px">
+                                            <label class="control-label" for="newPassword">新密码:</label>
+                                            <input type="text" class="form-control" v-model="newPassword" ref="newPassword" size="40%" id="newPassword" />
+                                        </div>
+<!--                                        <div style="margin-top: 30px">-->
+<!--                                            <label class="control-label" for="newPassword2">再次输入新密码:</label>-->
+<!--                                            <input type="text" class="form-control" v-model="newPassword2" ref="newPassword2" size="40%" id="newPassword2" />-->
+<!--                                        </div>-->
+                                    </div>
+                                    <div class="modal-footer">
+                                        <button type="button" class="btn btn-default" data-dismiss="modal" @click="closeUpdatePasswordDialog" >关闭</button>
+                                        <button type="button" class="btn btn-primary" @click="updatePassword">修改</button>
                                     </div>
                                 </div>
                             </div>
@@ -314,11 +348,11 @@
                                     <div class="modal-body">
                                         <div>
                                             <label for="customPhone" class="control-label">会员码:</label>
-                                            <input autocomplete="off" type="text" ref="couponBarCode" size="60%" id="couponBarCode" @on-enter="calculateOrderPriceSubmit" />
+                                            <input autocomplete="off" type="text" v-model="memberCode" ref="couponBarCode" size="60%" id="couponBarCode" @on-enter="calculateOrderPriceSubmit" />
                                         </div>
                                         <div style="margin-top: 30px">
-                                            <label class="control-label" >是否用积分进行抵扣:</label>
-                                            <i-switch v-model="switch1" />
+                                            <label class="control-label" >是否使用积分进行抵扣:</label>
+                                            <i-switch v-model="switch1" on />
                                         </div>
                                     </div>
                                     <div class="modal-footer">
@@ -340,14 +374,14 @@
                                     <div class="modal-body">
                                         <div style="margin-bottom: 50px">
                                             <ul style="display: inline-block">
-                                                <li><h5 style="border: white;padding: 8px;">总件数:{{totalCount}}</h5></li>
-                                                <li><h5 style="border: white;padding: 8px;">总价:{{totalPrice}}</h5></li>
-                                                <li><h5 style="border: white;padding: 8px;color: red;">实际支付价:{{actualPrice}}</h5></li>
+                                                <li><h3 style="border: white;padding: 8px;">总件数:{{totalCount}}</h3></li>
+                                                <li><h3 style="border: white;padding: 8px;">总价:{{totalPrice}}</h3></li>
+                                                <li><h3 style="border: white;padding: 8px;color: red;">实际支付价:{{actualPrice}}</h3></li>
                                             </ul>
                                             <ul style="display: inline-block">
-                                                <li><h5 style="border: white;padding: 8px">会员等级:{{levelName}}</h5></li>
-                                                <li><h5 style="border: white;padding: 8px">会员当前积分:{{memberCurrentAvailableScore}}</h5></li>
-                                                <li><h5 style="border: white;padding: 8px">抵扣积分:{{deductionScore}}</h5></li>
+                                                <li><h3 style="border: white;padding: 8px">会员等级:{{levelName}}</h3></li>
+                                                <li><h3 style="border: white;padding: 8px">会员当前积分:{{memberCurrentAvailableScore}}</h3></li>
+                                                <li><h3 style="border: white;padding: 8px">抵扣积分:{{deductionScore}}</h3></li>
                                             </ul>
                                         </div>
                                         <form>

+ 7 - 7
kmall-admin/src/main/webapp/WEB-INF/page/shop/offilineOrderList.html

@@ -49,7 +49,7 @@
                 <i-button @click="reloadSearch">重置</i-button>
             </div>
             <div>
-                <i-button type="info" @click="checkOrderRestore"></i>&nbsp;查验单恢复库存</i-button>
+<!--                <i-button type="info" @click="checkOrderRestore"></i>&nbsp;查验单恢复库存</i-button>-->
                 #if($shiro.hasPermission("order:exportOffilineOrder"))
                 <i-button type="primary" @click="exportOffilineOrder"><i class="fa fa-cloud-download"></i>&nbsp;导出</i-button>
                 #end
@@ -146,15 +146,15 @@
                             </Radio>
                         </Radio-group>
                     </Form-item>
-                    <!--<Form-item label="收货人" prop="consignee">-->
-                        <!--<i-input v-model="order.consignee" readonly/>-->
-                    <!--</Form-item>-->
+                    <Form-item label="收货人" prop="payName">
+                        <i-input v-model="order.payName" readonly/>
+                    </Form-item>
                     <!--<Form-item label="收货地址" prop="address">-->
                         <!--<i-input v-model="order.address" readonly/>-->
                     <!--</Form-item>-->
-                    <!--<Form-item label="联系电话" prop="mobile">-->
-                        <!--<i-input v-model="order.mobile" readonly/>-->
-                    <!--</Form-item>-->
+                    <Form-item label="手机号" prop="mobile">
+                        <i-input v-model="order.mobile" readonly/>
+                    </Form-item>
                     <!--<Form-item label="客户留言" prop="postscript">-->
                         <!--<i-input v-model="order.postscript" readonly/>-->
                     <!--</Form-item>-->

+ 103 - 0
kmall-admin/src/main/webapp/WEB-INF/page/shop/stockchangerecord.html

@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>海控出入库单记录</title>
+    #parse("sys/header.html")
+</head>
+<body>
+<div id="rrapp" v-cloak>
+	<div v-show="showList">
+        <Row :gutter="16">
+            <div class="search-group">
+                <i-col span="5">
+                    <i-select v-model="q.storeId" placeholder="门店编号" filterable label-in-value>
+                        <i-option v-for="store in stores" :value="store.id"
+                                  :key="store.id">{{store.storeName}}
+                        </i-option>
+                    </i-select>
+                </i-col>
+                <i-col span="3">
+                    <i-input v-model="q.sku" @on-enter="query" placeholder="sku"/>
+                </i-col>
+                <i-col span="3">
+                    <i-select v-model="q.type" placeholder="出入库类型"
+                              label-in-value>
+                        <i-option v-for="macro in macros" :value="macro.value" :key="macro.id">{{macro.name}}
+                        </i-option>
+                    </i-select>
+                </i-col>
+                <i-button @click="query">查询</i-button>
+                <i-button @click="reloadSearch">重置</i-button>
+            </div>
+            <div class="buttons-group" style="width: 100%;margin-top: 8px;">
+                <i-col style="display: inline-grid;">
+                    <Upload :show-upload-list="false" :on-success="uploadExcelSuccess" :on-error="uploadExcelError" :on-format-error="uploadExcelFormatError"
+                            :format="['xls','xlsx']"
+                            action="../stockchangerecord/upload" :before-upload="beforeUpload"  :data="uploadData" >
+                        <i-button type="ghost" icon="ios-cloud-upload-outline">导入</i-button>
+                    </Upload>
+                </i-col>
+                <a href="../statics/file/stock_change_record.xlsx">出入库单导入模板下载</a>
+            </div>
+            <div class="buttons-group">
+                <i-button type="info" @click="add"><i class="fa fa-plus"></i>&nbsp;新增</i-button>
+                <i-button type="warning" @click="update"><i class="fa fa-pencil-square-o"></i>&nbsp;修改</i-button>
+                <i-button type="error" @click="del"><i class="fa fa-trash-o"></i>&nbsp;删除</i-button>
+            </div>
+        </Row>
+	    <table id="jqGrid"></table>
+	    <div id="jqGridPager"></div>
+    </div>
+
+    <Card v-show="!showList">
+        <p slot="title">{{title}}</p>
+		<i-form ref="formValidate" :model="stockChangeRecord" :rules="ruleValidate" :label-width="80">
+            <Form-item label="商户" prop="merchSn">
+                <i-select v-model="stockChangeRecord.merchSn" filterable placeholder="商户" @on-change="changeMerch" label-in-value>
+                    <i-option v-for="merch in merchList" :value="merch.merchSn" :key="merch.merchSn">{{merch.merchName}}</i-option>
+                </i-select>
+            </Form-item>
+            <Form-item label="第三方商户" prop="thirdMerchSn">
+                <i-select v-model="stockChangeRecord.thirdMerchSn" filterable placeholder="第三方商户" @on-change="changeThirdMerchantBiz" 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="门店id" prop="storeId">
+                <i-select v-model="stockChangeRecord.storeId" filterable placeholder="活动门店" label-in-value>
+                    <i-option v-for="store in storeList" :value="store.id" :key="store.id">{{store.storeName}}</i-option>
+                </i-select>
+            </Form-item>
+            <Form-item label="sku" prop="sku">
+                <i-input v-model="stockChangeRecord.sku" placeholder="sku"/>
+            </Form-item>
+            <Form-item label="类型" prop="type">
+                <i-select v-model="stockChangeRecord.type" placeholder="记录类型,0:出库 1:入库">
+                    <i-option value="0">出库</i-option>
+                    <i-option value="1">入库</i-option>
+                </i-select>
+            </Form-item>
+            <Form-item label="数量" prop="number">
+                <i-input v-model="stockChangeRecord.number" placeholder="出库或入库数量"/>
+            </Form-item>
+            <Form-item label="备注" prop="remark">
+                <i-input v-model="stockChangeRecord.remark" placeholder="备注"/>
+            </Form-item>
+<!--            <Form-item label="创建时间" prop="createTime">-->
+<!--                <i-input v-model="stockChangeRecord.createTime" placeholder=""/>-->
+<!--            </Form-item>-->
+<!--            <Form-item label="修改时间" prop="modifyTime">-->
+<!--                <i-input v-model="stockChangeRecord.modifyTime" placeholder=""/>-->
+<!--            </Form-item>-->
+            <Form-item>
+                <i-button type="primary" @click="handleSubmit('formValidate')">提交</i-button>
+                <i-button type="warning" @click="reload" style="margin-left: 8px"/>返回</i-button>
+                <i-button type="ghost" @click="handleReset('formValidate')" style="margin-left: 8px">重置</i-button>
+            </Form-item>
+        </i-form>
+	</Card>
+</div>
+
+<script src="${rc.contextPath}/js/shop/stockchangerecord.js?_${date.systemTime}"></script>
+</body>
+</html>

+ 125 - 3
kmall-admin/src/main/webapp/js/sale/sale.js

@@ -624,7 +624,12 @@ let vm = new Vue({
         // 是否点击了计算活动价格
         calActivityFlag: false,
         // 是否适用积分进行抵扣
-        switch1: true
+        switch1: true,
+        // 旧密码
+        oldPassword: '',
+        // 新密码
+        newPassword: '',
+        newPassword2: ''
     },
     watch: {
         prodBarcode (){
@@ -699,6 +704,10 @@ let vm = new Vue({
         query: function () {
             vm.storeId = sessionStorage.getItem("storeId");
             var thisGoods = {};
+            // 挂起后的新订单默认开启
+            if (vm.pendingOrderMap != null || vm.pendingOrderMap.size > 0) {
+                vm.switch1 = true;
+            }
             var overflowLi = this.$refs.overflowLi;
             // console.log("vm.$refs.saomiao.value===>" + vm.$refs.saomiao.value);
             let scanSellVolume = calScanSellVolume(vm.$refs.saomiao.value);
@@ -945,6 +954,8 @@ let vm = new Vue({
             vm.levelName = '';
             vm.deductionScore = '';
             vm.memberCurrentAvailableScore = '';
+            vm.memberCode = '';
+            vm.switch1 = true;
             vm.clickFlag = true;
             vm.calActivityFlag = false;
             vm.customClearData();
@@ -957,7 +968,9 @@ let vm = new Vue({
             vm.levelName = '';
             vm.deductionScore = '';
             vm.memberCurrentAvailableScore = '';
+            vm.memberCode = '';
             vm.clickFlag = true;
+            vm.switch1 = true;
             vm.calActivityFlag = false;
             $('#pendignOrderModal').modal('show');
         },
@@ -981,6 +994,8 @@ let vm = new Vue({
             vm.pendingOrderMap.delete(key);
 
             vm.clickFlag = true;
+            vm.memberCode = '';
+            vm.switch1 = true;
             vm.calActivityFlag = false;
             removeByValue(vm.pendingOrderKeys,key);
             $('#pendignOrderModal').modal('hide')
@@ -1007,7 +1022,6 @@ let vm = new Vue({
                 customPhone = '';
             }
             vm.$refs.customPhone.value = customPhone;
-            vm.$refs.couponBarCode.value = "";
             if(vm.$refs.couponSn)
                 vm.$refs.couponSn.value = "";
             this.userInfo.couponSn = "";
@@ -1395,7 +1409,113 @@ let vm = new Vue({
                     this.$refs.payCode.focus();
                 }, 200);
             })
-        }
+        },
+        /**
+         * 2021/12/27
+         * 实名认证
+         */
+        idCardVerification:function (){
+            var custimName=this.$refs.customName.value;
+            var customIDCard=this.$refs.customIDCard.value;
+            if (custimName==''){
+                alert("请输入姓名");
+                return;
+            }
+            if (customIDCard==''){
+                alert("请输入身份证");
+                return;
+            }
+            $.ajax({
+                type: "POST",
+                url: "../api/index/idCardVerification",
+                contentType: "application/json",
+                data: JSON.stringify({'idNo':customIDCard,'userName':custimName}),
+                success: function (r) {
+                    if (r.errno==0){
+                        //实名认证成功则调用去付款方法
+                        $('#myModal').modal('hide');
+                        vm.submitCustomInfo();
+                    }else{
+                        alert(r.errmsg)
+                        $('#myModal').modal('show');
+                        return;
+                    }
+
+
+                }
+            });
+
+        },
+        updatePasswordOpen : function () {
+            vm.oldPassword = '';
+            vm.newPassword = '';
+            vm.newPassword2 = '';
+            $("#updatePasswordDialog").modal('show');
+        },
+        closeUpdatePasswordDialog : function () {
+            vm.oldPassword = '';
+            vm.newPassword = '';
+            vm.newPassword2 = '';
+            $("#updatePasswordDialog").modal('hide');
+        },
+        updatePassword: function () {
+
+            let oldPassword = vm.oldPassword;
+            let newPassword = vm.newPassword;
+            // let newPassword2 = vm.newPassword2;
+
+            if (oldPassword === 'null' || oldPassword === null || oldPassword === '' || oldPassword === 'undefined') {
+                alert("原密码不能为空!");
+                return;
+            }
+
+            if (newPassword === 'null' || newPassword === null || newPassword === '' || newPassword === 'undefined') {
+                alert("新密码不能为空!");
+                return;
+            }
+            // if (newPassword2 === 'null' || newPassword2 === null || newPassword2 === '' || newPassword2 === 'undefined') {
+            //     alert("第二次输入的新密码不能为空!");
+            //     return;
+            // }
+
+            // if (newPassword2 !== newPassword) {
+            //     alert("新密码不一致!");
+            //     return;
+            // }
+
+            // if (newPassword === oldPassword && oldPassword === newPassword2) {
+            //     alert("输入的密码相同!");
+            //     return;
+            // }
+            if (newPassword === oldPassword) {
+                alert("输入的密码相同!");
+                return;
+            }
+
+            if (newPassword.length < 6) {
+                alert("新密码必须大于6位!");
+                return;
+            }
+
+            var data = "password=" + oldPassword + "&newPassword=" + newPassword;
+            $.ajax({
+                type: "POST",
+                url: "../sys/user/password",
+                data: data,
+                dataType: "json",
+                success: function (result) {
+                    if (result.code == 0) {
+                        alert("修改成功!", function () {
+                            location.reload();
+                        });
+                    } else {
+                        alert(result.msg);
+                    }
+                }
+            });
+        },
+
+
     }
 });
 
@@ -2094,6 +2214,8 @@ function toPayOrder(payCode){
                     vm.levelName = '';
                     vm.deductionScore = '';
                     vm.memberCurrentAvailableScore = '';
+                    vm.memberCode = "";
+                    vm.switch1 = true;
                     vm.clickFlag = false;
                     vm.customClearData();
 

+ 4 - 0
kmall-admin/src/main/webapp/js/shop/mngchange.js

@@ -16,6 +16,10 @@ $(function () {
                         return '更新库存增加';
                     } else if (value == '4') {
                         return '更新库存减少';
+                    } else if (value == '5') {
+                        return '出库单';
+                    } else if (value == '6') {
+                        return '入库单';
                     }
                     return '-';
                 }

+ 238 - 0
kmall-admin/src/main/webapp/js/shop/stockchangerecord.js

@@ -0,0 +1,238 @@
+$(function () {
+    $("#jqGrid").jqGrid({
+        url: '../stockchangerecord/list',
+        datatype: "json",
+        colModel: [
+			{label: 'id', name: 'id', index: 'id', key: true, hidden: true},
+			{label: '门店id', name: 'storeId', index: 'store_id', width: 40, align: 'center'},
+			{label: 'sku', name: 'sku', index: 'sku', width: 60, align: 'center'},
+			{label: '类型', name: 'type', index: 'type', width: 40, align: 'center', formatter:function (value) {
+				if (value === '0') {
+					return '出库';
+				} else {
+					return '入库';
+				}
+			}},
+			{label: '数量', name: 'number', index: 'number', width: 30, align: 'center'},
+			{label: '备注', name: 'remark', index: 'remark', width: 120, align: 'center'},
+			{label: '创建时间', name: 'createTime', index: 'create_time', width: 140, align: 'center', formatter:function (value) {
+				return new Date(value);
+			}},
+			{label: '修改时间', name: 'modifyTime', index: 'modify_time', width: 140, align: 'center', formatter:function (value) {
+				return new Date(value);
+			}},
+			{label: '订单编号', name: 'orderSn', index: 'order_sn', width: 60, align: 'center'}
+			],
+		viewrecords: true,
+        height: 550,
+        rowNum: 10,
+        rowList: [10, 30, 50],
+        rownumbers: true,
+        rownumWidth: 25,
+        autowidth: true,
+        multiselect: true,
+        pager: "#jqGridPager",
+        jsonReader: {
+            root: "page.list",
+            page: "page.currPage",
+            total: "page.totalPage",
+            records: "page.totalCount"
+        },
+        prmNames: {
+            page: "page",
+            rows: "limit",
+            order: "order"
+        },
+        gridComplete: function () {
+            $("#jqGrid").closest(".ui-jqgrid-bdiv").css({"overflow-x": "hidden"});
+        },
+        changeThirdMerchantBiz: function (opt) {
+			var value = opt.value;
+			$.get("../store/getStoresByThirdMerch?thirdPartyMerchCode=" + value, function (r) {
+				vm.storeList = r.list;
+			});
+		}
+    });
+});
+
+let vm = new Vue({
+	el: '#rrapp',
+	data: {
+        showList: true,
+        title: null,
+		stockChangeRecord: {},
+		ruleValidate: {
+			name: [
+				{required: true, message: '名称不能为空', trigger: 'blur'}
+			]
+		},
+		q: {
+		    name: ''
+		},
+		merchList: {},//商户
+		thirdMerchantBizList: {},//第三方商户
+		storeList: {},//门店
+		uploadData:[],
+		stores: [],
+		macros: []
+	},
+	methods: {
+		query: function () {
+			vm.reload();
+		},
+		add: function () {
+			vm.showList = false;
+			vm.title = "新增";
+			vm.stockChangeRecord = {};
+			vm.getMerchList();
+		},
+		update: function (event) {
+            let id = getSelectedRow();
+			if (id == null) {
+				return;
+			}
+			vm.showList = false;
+            vm.title = "修改";
+			vm.getMerchList();
+
+            vm.getInfo(id);
+		},
+		saveOrUpdate: function (event) {
+            let url = vm.stockChangeRecord.id == null ? "../stockchangerecord/save" : "../stockchangerecord/update";
+			let s = JSON.stringify(vm.stockChangeRecord);
+			console.log("请求参数===> " + s);
+
+            $.ajax({
+				type: "POST",
+			    url: url,
+			    contentType: "application/json",
+			    data: s,
+                success: function (r) {
+                    if (r.code === 0) {
+                        alert('操作成功', function (index) {
+                            vm.reload();
+                        });
+                    } else {
+                        alert(r.msg);
+                    }
+                }
+			});
+		},
+		del: function (event) {
+            let ids = getSelectedRows();
+			if (ids == null){
+				return;
+			}
+
+			confirm('确定要删除选中的记录?', function () {
+				$.ajax({
+					type: "POST",
+				    url: "../stockchangerecord/delete",
+				    contentType: "application/json",
+				    data: JSON.stringify(ids),
+				    success: function (r) {
+						if (r.code == 0) {
+							alert('操作成功', function (index) {
+								$("#jqGrid").trigger("reloadGrid");
+							});
+						} else {
+							alert(r.msg);
+						}
+					}
+				});
+			});
+		},
+		getInfo: function(id){
+			$.get("../stockchangerecord/info/"+id, function (r) {
+                vm.stockChangeRecord = r.stockChangeRecord;
+            });
+		},
+        reloadSearch: function() {
+            vm.q = {
+                name: ''
+            }
+            vm.reload();
+		},
+		reload: function (event) {
+			vm.showList = true;
+            let page = $("#jqGrid").jqGrid('getGridParam', 'page');
+			$("#jqGrid").jqGrid('setGridParam', {
+                postData: {
+                	'storeId': vm.q.storeId,
+					'type': vm.q.type,
+					'sku': vm.q.sku
+				},
+                page: page
+            }).trigger("reloadGrid");
+            vm.handleReset('formValidate');
+		},
+        handleSubmit: function (name) {
+            handleSubmitValidate(this, name, function () {
+                vm.saveOrUpdate()
+            });
+        },
+        handleReset: function (name) {
+            handleResetForm(this, name);
+        },
+		uploadExcelSuccess: function (data) {
+			if(data.code==0){
+				alert('导入成功', function (index) {
+					$("#jqGrid").trigger("reloadGrid");
+				});
+			}else{
+				alert(data.msg);
+			}
+		},
+		uploadExcelError: function () {
+			alert('上传出现异常,请重试!');
+		},
+		uploadExcelFormatError: function (file) {
+			this.$Notice.warning({
+				title: '文件格式不正确',
+				desc: '文件 ' + file.name + ' 格式不正确,请上传 xls 或 xlsx 格式的文件。'
+			});
+		},beforeUpload(){
+			vm.uploadData = {
+				storeId: vm.storeId,
+				mkaId : vm.mkaId
+			}
+			let promise = new Promise((resolve) => {
+				this.$nextTick(function () {
+					resolve(true);
+				});
+			});
+			return promise; //通过返回一个promis对象解决
+
+		},
+		getMerchList: function() {
+			$.get("../merch/queryAll", function (r) {
+				vm.merchList = r.list;
+			});
+		},
+		changeMerch: function(opt) {
+			var value = opt.value;
+			vm.getThirdMerchantBizList(value);
+		},
+		getThirdMerchantBizList: function(merchSn) {
+			$.get("../thirdmerchantbiz/queryAll?merchSn=" + merchSn, function (r) {
+				vm.thirdMerchantBizList = r.list;
+			});
+		},
+		changeThirdMerchantBiz: function (opt) {
+			var value = opt.value;
+			$.get("../store/getStoresByThirdMerch?thirdPartyMerchCode=" + value, function (r) {
+				vm.storeList = r.list;
+			});
+		},
+	},
+	mounted() {
+		$.get("../store/queryAll", function (r) {
+			vm.stores = r.list;
+		});
+
+		$.get("../sys/macro/queryMacrosByValue?value=stockChangeType", function (r) {
+			vm.macros = r.list;
+		});
+
+	}
+});

+ 4 - 0
kmall-admin/src/main/webapp/js/shop/storemngchange.js

@@ -16,6 +16,10 @@ $(function () {
                         return '更新库存增加';
                     } else if (value == '4') {
                         return '更新库存减少';
+                    } else if (value == '5') {
+                        return '出库单';
+                    } else if (value == '6') {
+                        return '入库单';
                     }
                     return '-';
                 }

BIN
kmall-admin/src/main/webapp/statics/file/stock_change_record.xlsx


+ 22 - 0
kmall-api/src/main/java/com/kmall/api/api/ApiIndexController.java

@@ -139,6 +139,28 @@ public class ApiIndexController extends ApiBaseAction {
             return toResponsFail("系统异常");
         }
     }
+
+    /**
+     *  实名认证
+     * @param
+     * @return
+     */
+    @RequestMapping("idCardVerification")
+    @IgnoreAuth
+    public Object idCardVerification(){
+        //实名认证身份证信息
+        JSONObject jsonParam = getJsonRequest();
+        String idNo = jsonParam.getString("idNo");
+        String userName = jsonParam.getString("userName");
+        String result = IdCardUtil.checkIdCard(idNo, userName);
+        logger.info("idcard check result:"+result);
+        IdCardMsgVo vo = JSON.parseObject(result,IdCardMsgVo.class);
+        if(vo.getRespCode().equalsIgnoreCase("0000")){
+            return toResponsMsgSuccess("实名认证成功");
+        }else{
+            return toResponsFail(vo.getRespMessage());
+        }
+    }
     public static void main(String[] args) {
 
     }

+ 5 - 2
kmall-common/src/main/java/com/kmall/common/constant/Dict.java

@@ -953,14 +953,17 @@ public class Dict {
     }
 
     /**
-     * 变动类型 0:还原 1:扣减 2:新增调整 3:更新调整增加 4:更新调整减少
+     * 变动类型 0:还原 1:扣减 2:新增调整 3:更新调整增加 4:更新调整减少 5:出库单 6:入库单
      */
     public enum changeType {
         item_0("0", "还原"),
         item_1("1", "扣减"),
         item_2("2", "新增调整"),
         item_3("3", "更新调整增加"),
-        item_4("4", "更新调整减少");
+        item_4("4", "更新调整减少"),
+        item_5("5", "出库单"),
+        item_6("6", "入库单"),
+        ;
 
         private String item;
         private String itemName;

+ 2 - 0
kmall-common/src/main/java/com/kmall/common/constant/JxlsXmlTemplateName.java

@@ -42,6 +42,8 @@ public class JxlsXmlTemplateName {
     public static final String FREE_GOODS_DTO_LIST = "/XmlTemplate/FreeGoodsDtoList.xml";
     // 积分抵扣商品导入
     public static final String SCORE_REDUCTION_DTO_LIST = "/XmlTemplate/ScoreReductionDTOList.xml";
+    // 出入库单记录导入
+    public static final String STOCK_CHANGE_RECORD_DTO_LIST = "/XmlTemplate/StockChangeRecordDtoList.xml";
     // 优惠券商品导入
     public static final String COUPON_MERCHANDISE_DTO_LIST = "/XmlTemplate/CouponMerchandiseDtoList.xml";
     // 组合价商品导入

+ 1 - 0
kmall-manager/src/main/resources/conf/redis.properties

@@ -32,6 +32,7 @@ redis.dev.pool.testOnBorrow=true
 # \u751F\u4EA7\u73AF\u5883
 redis.prod.keyPrefix=platform
 redis.prod.host=127.0.0.1
+#redis.prod.host=120.76.119.218
 redis.prod.port=6379
 redis.prod.password=e415MBsvV7
 redis.prod.pool.maxIdle=200

+ 13 - 0
sql/init/other_table.sql

@@ -4054,4 +4054,17 @@ CREATE TABLE `wx_cb_pay_doc`  (
   PRIMARY KEY (`wx_pay_sn`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '微信跨境支付单证' ROW_FORMAT = Compact;
 
+CREATE TABLE `mall_stock_change_record` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `store_id` int(11) DEFAULT NULL COMMENT '门店id',
+  `warehouse_sn` int(11) DEFAULT NULL COMMENT '仓库编号',
+  `sku` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'sku',
+  `type` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '记录类型,0:出库 1:入库',
+  `number` int(8) DEFAULT NULL COMMENT '出库或入库数量',
+  `remark` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '备注',
+  `create_time` datetime DEFAULT NULL,
+  `modify_time` datetime DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='海控出入库单记录';
+
 SET FOREIGN_KEY_CHECKS = 1;

+ 18 - 0
sql/init/sys_table.sql

@@ -679,6 +679,24 @@ INSERT INTO `sys_menu` VALUES (909, 394, '修改', NULL, 'address:update', 2, NU
 INSERT INTO `sys_menu` VALUES (915, 942, '接口日志', 'shop/interfacesendlog.html', 'fa fa-eye', 1, 'fa fa-file-text-o', 0, 0);
 INSERT INTO `sys_menu` VALUES (916, 915, '查询', NULL, 'tinterfacesendlog:info,interfacesendlog:list', 2, NULL, 0, 0);
 INSERT INTO `sys_menu` VALUES (942, 0, '日志记录', NULL, NULL, 0, 'fa fa-file-text-o', 10, 0);
+
+INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `status`)
+    VALUES ('357', '出入库单记录', 'shop/stockchangerecord.html', NULL, '1', 'fa fa-file-code-o', '6', '0');
+-- 按钮父菜单ID
+set @parentId = @@identity;
+
+-- 菜单对应按钮SQL
+INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `status`)
+    SELECT @parentId, '查看', null, 'stockchangerecord:list,stockchangerecord:info', '2', null, '6', '0';
+INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `status`)
+    SELECT @parentId, '新增', null, 'stockchangerecord:save', '2', null, '6', '0';
+INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `status`)
+    SELECT @parentId, '修改', null, 'stockchangerecord:update', '2', null, '6', '0';
+INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `status`)
+    SELECT @parentId, '删除', null, 'stockchangerecord:delete', '2', null, '6', '0';
+
+
+
 -- 菜单SQL
 INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`, `status`)
     VALUES ('942', '会员同步消费订单记录', 'shop/haikongmemberordersyncresend.html', NULL, '1', 'fa fa-file-code-o', '6', '0');