Browse Source

商品类型编码修改,商品信息修改

huang 19 hours ago
parent
commit
6932537551
26 changed files with 2085 additions and 1650 deletions
  1. 3 0
      docs/new_sql.sql
  2. 117 15
      src/main/java/com/jsh/erp/controller/MaterialController.java
  3. 10 87
      src/main/java/com/jsh/erp/datasource/entities/DepotItemVo4DetailByTypeAndMId.java
  4. 28 4
      src/main/java/com/jsh/erp/datasource/entities/DepotItemVo4WithInfoEx.java
  5. 3 0
      src/main/java/com/jsh/erp/datasource/entities/Material.java
  6. 10 9
      src/main/java/com/jsh/erp/datasource/entities/MaterialCategory.java
  7. 39 12
      src/main/java/com/jsh/erp/datasource/entities/MaterialVo4Unit.java
  8. 5 0
      src/main/java/com/jsh/erp/datasource/mappers/MaterialCategoryMapper.java
  9. 1 1
      src/main/java/com/jsh/erp/datasource/mappers/MaterialCategoryMapperEx.java
  10. 14 0
      src/main/java/com/jsh/erp/datasource/mappers/MaterialExtendMapper.java
  11. 9 2
      src/main/java/com/jsh/erp/datasource/mappers/MaterialExtendMapperEx.java
  12. 2 1
      src/main/java/com/jsh/erp/datasource/mappers/MaterialMapper.java
  13. 8 4
      src/main/java/com/jsh/erp/datasource/mappers/MaterialMapperEx.java
  14. 22 0
      src/main/java/com/jsh/erp/datasource/vo/MaterialVo.java
  15. 4 53
      src/main/java/com/jsh/erp/datasource/vo/MaterialVoSearch.java
  16. 20 0
      src/main/java/com/jsh/erp/datasource/vo/UnitListVo.java
  17. 6 0
      src/main/java/com/jsh/erp/service/DepotService.java
  18. 2 1
      src/main/java/com/jsh/erp/service/MaterialCategoryService.java
  19. 12 3
      src/main/java/com/jsh/erp/service/MaterialExtendService.java
  20. 80 1441
      src/main/java/com/jsh/erp/service/MaterialService.java
  21. 1610 0
      src/main/java/com/jsh/erp/service/impl/MaterialServiceImpl.java
  22. 14 9
      src/main/resources/mapper_xml/DepotItemMapperEx.xml
  23. 5 1
      src/main/resources/mapper_xml/MaterialCategoryMapper.xml
  24. 19 2
      src/main/resources/mapper_xml/MaterialExtendMapper.xml
  25. 1 1
      src/main/resources/mapper_xml/MaterialMapper.xml
  26. 41 4
      src/main/resources/mapper_xml/MaterialMapperEx.xml

+ 3 - 0
docs/new_sql.sql

@@ -43,3 +43,6 @@ ADD COLUMN reason_of_difference VARCHAR(255) DEFAULT '' COMMENT '出入库差异
 ADD COLUMN warehousing_user BIGINT DEFAULT NULL COMMENT '出入库操作用户',
 ADD COLUMN warehousing_time DATE DEFAULT NULL COMMENT '出入库时间';
 
+-- 修改产品类型编码为BIGINT
+ALTER TABLE jsh_material_category MODIFY COLUMN serial_no BIGINT;
+

+ 117 - 15
src/main/java/com/jsh/erp/controller/MaterialController.java

@@ -8,13 +8,7 @@ import com.jsh.erp.datasource.entities.Material;
 import com.jsh.erp.datasource.entities.MaterialExtend;
 import com.jsh.erp.datasource.entities.MaterialVo4Unit;
 import com.jsh.erp.datasource.entities.Unit;
-import com.jsh.erp.service.DepotService;
-import com.jsh.erp.service.DepotItemService;
-import com.jsh.erp.service.MaterialService;
-import com.jsh.erp.service.RoleService;
-import com.jsh.erp.service.SystemConfigService;
-import com.jsh.erp.service.UnitService;
-import com.jsh.erp.service.UserService;
+import com.jsh.erp.service.*;
 import com.jsh.erp.utils.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -317,9 +311,9 @@ public class MaterialController extends BaseController {
             }
             List<MaterialVo4Unit> dataList = materialService.findBySelectWithBarCode(categoryId, q, StringUtil.toNull(standardOrModel),
                     StringUtil.toNull(color), StringUtil.toNull(brand), StringUtil.toNull(mfrs), enableSerialNumber, enableBatchNumber,
-                    (currentPage-1)*pageSize, pageSize);
+                    (currentPage-1)*pageSize, pageSize,depotId);
             int total = materialService.findBySelectWithBarCodeCount(categoryId, q, StringUtil.toNull(standardOrModel),
-                    StringUtil.toNull(color), StringUtil.toNull(brand), StringUtil.toNull(mfrs), enableSerialNumber, enableBatchNumber);
+                    StringUtil.toNull(color), StringUtil.toNull(brand), StringUtil.toNull(mfrs), enableSerialNumber, enableBatchNumber,depotId);
             object.put("total", total);
             JSONArray dataArray = new JSONArray();
             //存放数据json数组
@@ -327,6 +321,7 @@ public class MaterialController extends BaseController {
                 for (MaterialVo4Unit material : dataList) {
                     JSONObject item = new JSONObject();
                     item.put("id", material.getMeId()); //商品扩展表的id
+                    item.put("mid", material.getId()); //商品扩展表的id
                     String ratioStr = ""; //比例
                     Unit unit = new Unit();
                     if (material.getUnitId() == null) {
@@ -348,7 +343,7 @@ public class MaterialController extends BaseController {
                             ratioStr = "[" + unit.getRatioThree().stripTrailingZeros().toPlainString() + unit.getBasicUnit() + "]";
                         }
                     }
-                    item.put("mBarCode", material.getmBarCode());
+                    item.put("barCode", material.getBarCode());
                     item.put("name", material.getName());
                     item.put("mnemonic", material.getMnemonic());
                     item.put("categoryName", material.getCategoryName());
@@ -361,6 +356,17 @@ public class MaterialController extends BaseController {
                     item.put("sku", material.getSku());
                     item.put("enableSerialNumber", material.getEnableSerialNumber());
                     item.put("enableBatchNumber", material.getEnableBatchNumber());
+//                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+//                    String date = material.getProductionDate() == null ? null : sdf.format(material.getProductionDate());
+                    item.put("productionDate",material.getProductionDate());
+                    item.put("expiryNum",material.getExpiryNum());
+                    item.put("batchNumber",material.getBatchNumber());
+                    item.put("position",material.getPosition());
+                    item.put("supplierId",material.getSupplierId());
+                    item.put("supplierName",material.getSupplierName());
+                    item.put("depotId",material.getDepotId());
+                    item.put("depotName",material.getDepotName());
+                    item.put("unitId",material.getUnitId());
                     BigDecimal stock;
                     if(StringUtil.isNotEmpty(material.getSku())){
                         stock = depotItemService.getSkuStockByParam(depotId,material.getMeId(),null,null);
@@ -575,11 +581,11 @@ public class MaterialController extends BaseController {
     @GetMapping(value = "/getMaterialByBarCode")
     @ApiOperation(value = "根据条码查询商品信息")
     public BaseResponseInfo getMaterialByBarCode(@RequestParam("barCode") String barCode,
-                                          @RequestParam(value = "organId", required = false) Long organId,
-                                          @RequestParam(value = "depotId", required = false) Long depotId,
-                                          @RequestParam("mpList") String mpList,
-                                          @RequestParam(required = false, value = "prefixNo") String prefixNo,
-                                          HttpServletRequest request) throws Exception {
+                                                 @RequestParam(value = "organId", required = false) Long organId,
+                                                 @RequestParam(value = "depotId", required = false) Long depotId,
+                                                 @RequestParam("mpList") String mpList,
+                                                 @RequestParam(required = false, value = "prefixNo") String prefixNo,
+                                                 HttpServletRequest request) throws Exception {
         BaseResponseInfo res = new BaseResponseInfo();
         try {
             Long userId = userService.getUserId(request);
@@ -820,4 +826,100 @@ public class MaterialController extends BaseController {
         }
         return res;
     }
+
+    /**
+     * 根据批次号查询商品信息
+     * @return
+     * @throws Exception
+     */
+    @GetMapping(value = "/getMaterialByBatchNumber")
+    @ApiOperation(value = "根据批次号查询商品信息")
+    public BaseResponseInfo getMaterialByBatchNumber(@RequestParam("batchNumber") String batchNumber,
+                                                     @RequestParam(value = "organId", required = false) Long organId,
+                                                     @RequestParam(value = "depotId", required = false) Long depotId,
+                                                     @RequestParam("mpList") String mpList,
+                                                     @RequestParam(required = false, value = "prefixNo") String prefixNo,
+                                                     HttpServletRequest request) throws Exception {
+        BaseResponseInfo res = new BaseResponseInfo();
+        try {
+            Long userId = userService.getUserId(request);
+            String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
+            String[] mpArr = mpList.split(",");
+            //支持序列号查询,先根据序列号查询条码,如果查不到就直接查条码
+//            MaterialExtend materialExtend = materialService.getMaterialExtendBySerialNumber(barCode);
+//            if(materialExtend!=null && StringUtil.isNotEmpty(materialExtend.getBarCode())) {
+//                barCode = materialExtend.getBarCode();
+//            }
+            List<MaterialVo4Unit> list = materialService.getMaterialByBatchNumber(batchNumber);
+            if(list!=null && list.size()>0) {
+                for(MaterialVo4Unit mvo: list) {
+                    mvo.setMaterialOther(materialService.getMaterialOtherByParam(mpArr, mvo));
+                    if ("LSCK".equals(prefixNo) || "LSTH".equals(prefixNo)) {
+                        //零售价
+                        mvo.setBillPrice(mvo.getCommodityDecimal());
+                    } else if ("CGDD".equals(prefixNo) || "CGRK".equals(prefixNo) || "CGTH".equals(prefixNo)) {
+                        //采购价
+                        mvo.setBillPrice(mvo.getPurchaseDecimal());
+                    } else if("QTRK".equals(prefixNo) || "DBCK".equals(prefixNo) || "ZZD".equals(prefixNo) || "CXD".equals(prefixNo)
+                            || "PDLR".equals(prefixNo) || "PDFP".equals(prefixNo)) {
+                        //采购价-给录入界面按权限屏蔽
+                        mvo.setBillPrice(roleService.parseBillPriceByLimit(mvo.getPurchaseDecimal(), "buy", priceLimit, request));
+                    } if ("XSDD".equals(prefixNo) || "XSCK".equals(prefixNo) || "XSTH".equals(prefixNo) || "QTCK".equals(prefixNo)) {
+                        //销售价
+                        if(organId == null) {
+                            mvo.setBillPrice(mvo.getWholesaleDecimal());
+                        } else {
+                            //查询最后一单的销售价,实现不同的客户不同的销售价
+                            BigDecimal lastUnitPrice = depotItemService.getLastUnitPriceByParam(organId, mvo.getMeId(), prefixNo);
+                            mvo.setBillPrice(lastUnitPrice!=null? lastUnitPrice : mvo.getWholesaleDecimal());
+                        }
+                        //销售价-给录入界面按权限屏蔽价格
+                        if("QTCK".equals(prefixNo)) {
+                            mvo.setBillPrice(roleService.parseBillPriceByLimit(mvo.getWholesaleDecimal(), "sale", priceLimit, request));
+                        }
+                    }
+                    //仓库id
+//                    if (depotId == null) {
+//                        JSONArray depotArr = depotService.findDepotByCurrentUser();
+//                        for (Object obj : depotArr) {
+//                            JSONObject depotObj = JSONObject.parseObject(obj.toString());
+//                            if (depotObj.get("isDefault") != null) {
+//                                Boolean isDefault = depotObj.getBoolean("isDefault");
+//                                if (isDefault) {
+//                                    Long id = depotObj.getLong("id");
+//                                    if (!"CGDD".equals(prefixNo) && !"XSDD".equals(prefixNo)) {
+//                                        //除订单之外的单据才有仓库
+//                                        mvo.setDepotId(id);
+//                                    }
+//                                    getStockByMaterialInfo(mvo);
+//                                }
+//                            }
+//                        }
+//                    } else {
+//                        mvo.setDepotId(depotId);
+//                        getStockByMaterialInfo(mvo);
+//                    }
+                }
+            }
+            res.code = 200;
+            res.data = list;
+        } catch(Exception e){
+            logger.error(e.getMessage(), e);
+            res.code = 500;
+            res.data = "获取数据失败";
+        }
+        return res;
+    }
+
+    @GetMapping(value = "/getMaterialById")
+    @ApiOperation(value = "根据商品id查询商品及子表信息")
+    public BaseResponseInfo getMaterialById(@RequestParam("mid") Long materialId,
+                                          HttpServletRequest request)throws Exception {
+        BaseResponseInfo res = new BaseResponseInfo();
+        res.code = 200;
+        res.data = materialService.getMaterialById(materialId);
+        return res;
+    }
+
+
 }

+ 10 - 87
src/main/java/com/jsh/erp/datasource/entities/DepotItemVo4DetailByTypeAndMId.java

@@ -1,18 +1,27 @@
 package com.jsh.erp.datasource.entities;
 
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
 import java.math.BigDecimal;
 import java.util.Date;
 
+@Data
 public class DepotItemVo4DetailByTypeAndMId {
 
+    @ApiModelProperty("序列号")
     private String number;
 
+    @ApiModelProperty("商品条码")
     private String barCode;
 
+    @ApiModelProperty("商品名称")
     private String materialName;
 
+    @ApiModelProperty("出入库类型")
     private String type;
 
+    @ApiModelProperty("单据类型")
     private String subType;
 
     private BigDecimal bnum;
@@ -21,97 +30,11 @@ public class DepotItemVo4DetailByTypeAndMId {
 
     private BigDecimal allPrice;
 
+    @ApiModelProperty("商品单位")
     private String materialUnit;
 
     private String depotName;
 
     private Date otime;
 
-    public String getNumber() {
-        return number;
-    }
-
-    public void setNumber(String number) {
-        this.number = number;
-    }
-
-    public String getBarCode() {
-        return barCode;
-    }
-
-    public void setBarCode(String barCode) {
-        this.barCode = barCode;
-    }
-
-    public String getMaterialName() {
-        return materialName;
-    }
-
-    public void setMaterialName(String materialName) {
-        this.materialName = materialName;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public String getSubType() {
-        return subType;
-    }
-
-    public void setSubType(String subType) {
-        this.subType = subType;
-    }
-
-    public BigDecimal getBnum() {
-        return bnum;
-    }
-
-    public void setBnum(BigDecimal bnum) {
-        this.bnum = bnum;
-    }
-
-    public BigDecimal getUnitPrice() {
-        return unitPrice;
-    }
-
-    public void setUnitPrice(BigDecimal unitPrice) {
-        this.unitPrice = unitPrice;
-    }
-
-    public BigDecimal getAllPrice() {
-        return allPrice;
-    }
-
-    public void setAllPrice(BigDecimal allPrice) {
-        this.allPrice = allPrice;
-    }
-
-    public String getMaterialUnit() {
-        return materialUnit;
-    }
-
-    public void setMaterialUnit(String materialUnit) {
-        this.materialUnit = materialUnit;
-    }
-
-    public String getDepotName() {
-        return depotName;
-    }
-
-    public void setDepotName(String depotName) {
-        this.depotName = depotName;
-    }
-
-    public Date getOtime() {
-        return otime;
-    }
-
-    public void setOtime(Date otime) {
-        this.otime = otime;
-    }
 }

+ 28 - 4
src/main/java/com/jsh/erp/datasource/entities/DepotItemVo4WithInfoEx.java

@@ -1,7 +1,11 @@
 package com.jsh.erp.datasource.entities;
 
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
 import java.math.BigDecimal;
 
+@Data
 public class DepotItemVo4WithInfoEx extends DepotItem{
 
     private Long MId;
@@ -48,16 +52,36 @@ public class DepotItemVo4WithInfoEx extends DepotItem{
 
     private BigDecimal currentUnitPrice;
 
-    private String barCode;
-
     private BigDecimal weight;
 
-    private String position;
-
     private String imgName;
 
     private String brand;
 
+    @ApiModelProperty("生产日期")
+    private String productionDate;
+
+    @ApiModelProperty("保质期天数")
+    private Integer expiryNum;
+
+    @ApiModelProperty("供应商id")
+    private Long supplierId;
+
+    @ApiModelProperty("商品条码")
+    private String barCode;
+
+    @ApiModelProperty("批次号")
+    private String batchNumber;
+
+    @ApiModelProperty("库存")
+    private BigDecimal inventory;
+
+    @ApiModelProperty("仓位货架")
+    private String position;
+
+    @ApiModelProperty("供应商名称")
+    private String supplierName;
+
     public Long getMId() {
         return MId;
     }

+ 3 - 0
src/main/java/com/jsh/erp/datasource/entities/Material.java

@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
  * 产品表实体类(商品信息)
@@ -80,6 +81,8 @@ public class Material {
     @ApiModelProperty("无动销提醒周期")
     private String movingPinReminderCycle;
 
+    private List<MaterialExtend> list;
+
 
     public void setName(String name) {
         this.name = name == null ? null : name.trim();

+ 10 - 9
src/main/java/com/jsh/erp/datasource/entities/MaterialCategory.java

@@ -1,8 +1,17 @@
 package com.jsh.erp.datasource.entities;
 
+import lombok.Data;
+import lombok.experimental.Accessors;
+
 import java.util.Date;
 
+/**
+ * 产品类型表实体类
+ */
+@Data
+@Accessors(chain = true)
 public class MaterialCategory {
+
     private Long id;
 
     private String name;
@@ -13,7 +22,7 @@ public class MaterialCategory {
 
     private String sort;
 
-    private String serialNo;
+    private Long serialNo;
 
     private String remark;
 
@@ -65,14 +74,6 @@ public class MaterialCategory {
         this.sort = sort == null ? null : sort.trim();
     }
 
-    public String getSerialNo() {
-        return serialNo;
-    }
-
-    public void setSerialNo(String serialNo) {
-        this.serialNo = serialNo == null ? null : serialNo.trim();
-    }
-
     public String getRemark() {
         return remark;
     }

+ 39 - 12
src/main/java/com/jsh/erp/datasource/entities/MaterialVo4Unit.java

@@ -4,12 +4,13 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 
 @Data
 public class MaterialVo4Unit extends Material{
 
-    //
+
     private String unitName;
 
     private BigDecimal ratio;
@@ -52,8 +53,22 @@ public class MaterialVo4Unit extends Material{
 
 //    private Long depotId;
 
+    /**
+     * 换算为大单位的库存
+     */
+    private String bigUnitStock;
+
+    /**
+     * 换算为大单位的初始库存
+     */
+    private String bigUnitInitialStock;
+
+    private String imgSmall;
+
+    private String imgLarge;
+
     @ApiModelProperty("生产日期")
-    private Date productionDate;
+    private String productionDate;
 
     @ApiModelProperty("保质期天数")
     private Integer expiryNum;
@@ -76,20 +91,26 @@ public class MaterialVo4Unit extends Material{
     @ApiModelProperty("仓位货架")
     private String position;
 
+    @ApiModelProperty("供应商名称")
+    private String supplierName;
 
-    /**
-     * 换算为大单位的库存
-     */
-    private String bigUnitStock;
+    @ApiModelProperty("仓库名称")
+    private String depotName;
 
-    /**
-     * 换算为大单位的初始库存
-     */
-    private String bigUnitInitialStock;
+    @ApiModelProperty("实际出入库数量")
+    private BigDecimal actualQuantityInStorage;
 
-    private String imgSmall;
+    @ApiModelProperty("出入库差异")
+    private BigDecimal warehousingVariance;
 
-    private String imgLarge;
+    @ApiModelProperty("出入库差异原因")
+    private String reasonOfDifference;
+
+    @ApiModelProperty("出入库用户")
+    private Long warehousingUser;
+
+    @ApiModelProperty("出入库时间")
+    private Date warehousingTime;
 
     public String getUnitName() {
         return unitName;
@@ -290,4 +311,10 @@ public class MaterialVo4Unit extends Material{
     public void setBigUnitInitialStock(String bigUnitInitialStock) {
         this.bigUnitInitialStock = bigUnitInitialStock;
     }
+
+    public void setProductionDate(Date productionDate) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        String date = productionDate == null ? null : sdf.format(productionDate);
+        this.productionDate = productionDate == null ? null : date;
+    }
 }

+ 5 - 0
src/main/java/com/jsh/erp/datasource/mappers/MaterialCategoryMapper.java

@@ -27,4 +27,9 @@ public interface MaterialCategoryMapper {
     int updateByPrimaryKeySelective(MaterialCategory record);
 
     int updateByPrimaryKey(MaterialCategory record);
+
+    /**
+     * 查询最大类型编码
+     */
+    Long selectMaxSerialNo();
 }

+ 1 - 1
src/main/java/com/jsh/erp/datasource/mappers/MaterialCategoryMapperEx.java

@@ -28,7 +28,7 @@ public interface MaterialCategoryMapperEx {
 
     int editMaterialCategory(MaterialCategory mc);
 
-    List<MaterialCategory> getMaterialCategoryBySerialNo(@Param("serialNo") String serialNo, @Param("id") Long id);
+    List<MaterialCategory> getMaterialCategoryBySerialNo(@Param("serialNo") Long serialNo, @Param("id") Long id);
 
     List<MaterialCategory> getMaterialCategoryListByCategoryIds(@Param("parentIds") String[] categoryIds);
 

+ 14 - 0
src/main/java/com/jsh/erp/datasource/mappers/MaterialExtendMapper.java

@@ -27,4 +27,18 @@ public interface MaterialExtendMapper {
     int updateByPrimaryKeySelective(MaterialExtend record);
 
     int updateByPrimaryKey(MaterialExtend record);
+
+    /**
+     * 根据商品id查询拓展行数据集合
+     * @param id id数组
+     */
+    List<MaterialExtend> selectByMId(@Param("id") Long id);
+
+    /**
+     * 根据批次号查询拓展行数据
+     * @param batchNumber
+     * @return
+     */
+    MaterialExtend selectByBatchNumber(@Param("batchNumber") String batchNumber);
+
 }

+ 9 - 2
src/main/java/com/jsh/erp/datasource/mappers/MaterialExtendMapperEx.java

@@ -9,6 +9,10 @@ import java.util.List;
 
 public interface MaterialExtendMapperEx {
 
+    /**
+     * 批量删除拓展表
+     * @param ids 拓展表id数组
+     */
     int batchDeleteMaterialExtendByIds(@Param("ids") String ids[]);
 
     List<MaterialExtendVo4List> getDetailList(
@@ -19,12 +23,15 @@ public interface MaterialExtendMapperEx {
             @Param("lastTime") Long lastTime,
             @Param("syncNum") Long syncNum);
 
+    /**
+     * 根据商品id数组查询拓展表数据
+     * @param ids 商品id数组
+     */
     List<MaterialExtend> getListByMId(@Param("ids") Long ids[]);
 
     int batchDeleteMaterialExtendByMIds(@Param("ids") String ids[]);
 
     int specialUpdatePrice(MaterialExtend record);
 
-    List<MaterialExtend> getBasicInfoByMid(
-            @Param("materialId") Long materialId);
+    List<MaterialExtend> getBasicInfoByMid(@Param("materialId") Long materialId);
 }

+ 2 - 1
src/main/java/com/jsh/erp/datasource/mappers/MaterialMapper.java

@@ -1,11 +1,12 @@
 package com.jsh.erp.datasource.mappers;
 
+import com.jsh.erp.datasource.entities.DepotItem;
 import com.jsh.erp.datasource.entities.Material;
 import com.jsh.erp.datasource.entities.MaterialExample;
 import java.util.List;
 import org.apache.ibatis.annotations.Param;
 
-public interface MaterialMapper {
+public interface MaterialMapper extends BaseMapperX<Material>{
     long countByExample(MaterialExample example);
 
     int deleteByExample(MaterialExample example);

+ 8 - 4
src/main/java/com/jsh/erp/datasource/mappers/MaterialMapperEx.java

@@ -2,12 +2,11 @@ package com.jsh.erp.datasource.mappers;
 
 import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.vo.MaterialVoSearch;
+import com.jsh.erp.datasource.vo.MaterialVo;
 import org.apache.ibatis.annotations.Param;
 
-import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Description
@@ -54,7 +53,8 @@ public interface MaterialMapperEx {
                                                   @Param("enableSerialNumber") String enableSerialNumber,
                                                   @Param("enableBatchNumber") String enableBatchNumber,
                                                   @Param("offset") Integer offset,
-                                                  @Param("rows") Integer rows);
+                                                  @Param("rows") Integer rows,
+                                                  @Param("depotId") Long depotId);
 
     int findBySelectWithBarCodeCount(@Param("idList") List<Long> idList,
                                      @Param("q") String q,
@@ -63,7 +63,8 @@ public interface MaterialMapperEx {
                                      @Param("brand") String brand,
                                      @Param("mfrs") String mfrs,
                                      @Param("enableSerialNumber") String enableSerialNumber,
-                                     @Param("enableBatchNumber") String enableBatchNumber);
+                                     @Param("enableBatchNumber") String enableBatchNumber,
+                                     @Param("depotId") Long depotId);
 
     List<MaterialVo4Unit> exportExcel(
             @Param("materialParam") String materialParam,
@@ -157,4 +158,7 @@ public interface MaterialMapperEx {
 
     MaterialExtend getMaterialExtendBySerialNumber(
             @Param("serialNumber") String serialNumber);
+
+    List<MaterialVo4Unit> getMaterialByBatchNumber(@Param("batchNumberArray") String [] batchNumberArray);
+
 }

+ 22 - 0
src/main/java/com/jsh/erp/datasource/vo/MaterialVo.java

@@ -0,0 +1,22 @@
+package com.jsh.erp.datasource.vo;
+
+import com.jsh.erp.datasource.entities.Material;
+import com.jsh.erp.datasource.entities.MaterialExtend;
+
+import java.util.List;
+
+/**
+ * 商品信息表加子表集合信息
+ */
+public class MaterialVo extends Material{
+
+    private List<MaterialExtend> list;
+
+    public List<MaterialExtend> getList() {
+        return list;
+    }
+
+    public void setList(List<MaterialExtend> list) {
+        this.list = list;
+    }
+}

+ 4 - 53
src/main/java/com/jsh/erp/datasource/vo/MaterialVoSearch.java

@@ -1,5 +1,8 @@
 package com.jsh.erp.datasource.vo;
 
+import lombok.Data;
+
+@Data
 public class MaterialVoSearch {
 
     private String barCode;
@@ -16,59 +19,7 @@ public class MaterialVoSearch {
 
     private String unit;
 
-    public String getBarCode() {
-        return barCode;
-    }
-
-    public void setBarCode(String barCode) {
-        this.barCode = barCode;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getMnemonic() {
-        return mnemonic;
-    }
-
-    public void setMnemonic(String mnemonic) {
-        this.mnemonic = mnemonic;
-    }
-
-    public String getStandard() {
-        return standard;
-    }
-
-    public void setStandard(String standard) {
-        this.standard = standard;
-    }
-
-    public String getModel() {
-        return model;
-    }
-
-    public void setModel(String model) {
-        this.model = model;
-    }
-
-    public String getColor() {
-        return color;
-    }
-
-    public void setColor(String color) {
-        this.color = color;
-    }
+    private String batchNumber;
 
-    public String getUnit() {
-        return unit;
-    }
 
-    public void setUnit(String unit) {
-        this.unit = unit;
-    }
 }

+ 20 - 0
src/main/java/com/jsh/erp/datasource/vo/UnitListVo.java

@@ -0,0 +1,20 @@
+package com.jsh.erp.datasource.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+
+@Data
+@Accessors(chain = true)
+public class UnitListVo {
+
+    @ApiModelProperty("单位名")
+    private String name;
+
+    @ApiModelProperty("单位比例")
+    private BigDecimal ratio;
+
+
+}

+ 6 - 0
src/main/java/com/jsh/erp/service/DepotService.java

@@ -268,6 +268,12 @@ public class DepotService {
         return id;
     }
 
+
+    /**
+     * 解析仓库列表
+     * @param depotId 仓库id
+     * @return 仓库id为空,返回当前用户有权限的仓库,不为空返回仓库id的集合
+     */
     public List<Long> parseDepotList(Long depotId) throws Exception {
         List<Long> depotList = new ArrayList<>();
         if(depotId !=null) {

+ 2 - 1
src/main/java/com/jsh/erp/service/MaterialCategoryService.java

@@ -122,6 +122,7 @@ public class MaterialCategoryService {
         MaterialCategory materialCategory = JSONObject.parseObject(obj.toJSONString(), MaterialCategory.class);
         materialCategory.setCreateTime(new Date());
         materialCategory.setUpdateTime(new Date());
+        materialCategory.setSerialNo(materialCategoryMapper.selectMaxSerialNo()+1);
         int result=0;
         try{
             result=materialCategoryMapper.insertSelective(materialCategory);
@@ -249,7 +250,7 @@ public class MaterialCategoryService {
         if(mc==null){
             return;
         }
-        if(StringUtil.isEmpty(mc.getSerialNo())){
+        if( mc.getSerialNo() < 0){
             return;
         }
         //根据商品类别编号查询商品类别

+ 12 - 3
src/main/java/com/jsh/erp/service/MaterialExtendService.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.jsh.erp.constants.BusinessConstants;
 import com.jsh.erp.constants.ExceptionConstants;
+import com.jsh.erp.datasource.entities.MaterialCurrentStock;
 import com.jsh.erp.datasource.entities.MaterialExtend;
 import com.jsh.erp.datasource.entities.MaterialExtendExample;
 import com.jsh.erp.datasource.entities.User;
@@ -96,8 +97,11 @@ public class MaterialExtendService {
         JSONArray meArr = obj.getJSONArray("meList");
         //添加商品拓展集合
         JSONArray insertedJson = new JSONArray();
+        //修改商品拓展集合
         JSONArray updatedJson = new JSONArray();
+        //移除商品集合
         JSONArray deletedJson = obj.getJSONArray("meDeleteIdList");
+
         JSONArray sortJson = JSONArray.parseArray(sortList);
         //添加/修改行数据处理
         if (null != meArr) {
@@ -346,7 +350,6 @@ public class MaterialExtendService {
     /**
      * 删除商品拓展行
      * @param ids 拓展行id集合
-     * @param request
      */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
     public int batchDeleteMaterialExtendByIds(String ids, HttpServletRequest request) throws Exception{
@@ -436,8 +439,7 @@ public class MaterialExtendService {
 
     public MaterialExtend getInfoByBarCode(String barCode)throws Exception {
         MaterialExtendExample example = new MaterialExtendExample();
-        example.createCriteria().andBarCodeEqualTo(barCode)
-                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
         List<MaterialExtend> list = materialExtendMapper.selectByExample(example);
         if(list!=null && list.size()>0) {
             return list.get(0);
@@ -469,6 +471,11 @@ public class MaterialExtendService {
         return 0;
     }
 
+    public MaterialExtend getInfoByBatchNumber(String batchNumber)throws Exception {
+        MaterialExtend example = materialExtendMapper.selectByBatchNumber(batchNumber);
+       return example;
+    }
+
     /**
      * 将Json对象的数据赋值到商品拓展对象中
      * @param tempJson
@@ -531,4 +538,6 @@ public class MaterialExtendService {
             materialExtend.setPosition(tempJson.getString("position"));
         }
     }
+
+
 }

+ 80 - 1441
src/main/java/com/jsh/erp/service/MaterialService.java

@@ -1,1526 +1,165 @@
 package com.jsh.erp.service;
 
-import com.alibaba.fastjson.JSON;
+
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.jsh.erp.constants.BusinessConstants;
-import com.jsh.erp.constants.ExceptionConstants;
 import com.jsh.erp.datasource.entities.*;
-import com.jsh.erp.datasource.mappers.*;
-import com.jsh.erp.datasource.vo.MaterialVoSearch;
-import com.jsh.erp.exception.BusinessRunTimeException;
-import com.jsh.erp.exception.JshException;
-import com.jsh.erp.utils.*;
-import jxl.Sheet;
-import jxl.Workbook;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
+import com.jsh.erp.utils.BaseResponseInfo;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.File;
 import java.math.BigDecimal;
-import java.util.*;
-
-@Service
-public class MaterialService {
-    private Logger logger = LoggerFactory.getLogger(MaterialService.class);
-
-    @Resource
-    private MaterialMapper materialMapper;
-    @Resource
-    private MaterialExtendMapper materialExtendMapper;
-    @Resource
-    private MaterialMapperEx materialMapperEx;
-    @Resource
-    private MaterialCategoryMapperEx materialCategoryMapperEx;
-    @Resource
-    private MaterialExtendMapperEx materialExtendMapperEx;
-    @Resource
-    private LogService logService;
-    @Resource
-    private UserService userService;
-    @Resource
-    private DepotItemMapperEx depotItemMapperEx;
-    @Resource
-    private DepotItemService depotItemService;
-    @Resource
-    private MaterialCategoryService materialCategoryService;
-    @Resource
-    private UnitService unitService;
-    @Resource
-    private MaterialInitialStockMapper materialInitialStockMapper;
-    @Resource
-    private MaterialInitialStockMapperEx materialInitialStockMapperEx;
-    @Resource
-    private MaterialCurrentStockMapper materialCurrentStockMapper;
-    @Resource
-    private MaterialCurrentStockMapperEx materialCurrentStockMapperEx;
-    @Resource
-    private DepotService depotService;
-    @Resource
-    private MaterialExtendService materialExtendService;
-    @Resource
-    private SystemConfigService systemConfigService;
-
-    @Value(value="${file.uploadType}")
-    private Long fileUploadType;
+import java.util.List;
+import java.util.Map;
 
-    public Material getMaterial(long id)throws Exception {
-        Material result=null;
-        try{
-            result=materialMapper.selectByPrimaryKey(id);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+public interface MaterialService {
+    Material getMaterial(long id)throws Exception;
 
-    public List<Material> getMaterialListByIds(String ids)throws Exception {
-        List<Long> idList = StringUtil.strToLongList(ids);
-        List<Material> list = new ArrayList<>();
-        try{
-            MaterialExample example = new MaterialExample();
-            example.createCriteria().andIdIn(idList);
-            list = materialMapper.selectByExample(example);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<Material> getMaterialListByIds(String ids)throws Exception;
 
-    public List<Material> getMaterial() throws Exception{
-        MaterialExample example = new MaterialExample();
-        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        List<Material> list=null;
-        try{
-            list=materialMapper.selectByExample(example);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<Material> getMaterial() throws Exception;
 
+    List<MaterialVo4Unit> select(String materialParam, String standard, String model, String color, String brand, String mfrs,
+                                 String materialOther, String weight, String expiryNum, String enableSerialNumber,
+                                 String enableBatchNumber, String position, String enabled, String remark, String categoryId,
+                                 String mpList)
+            throws Exception;
 
     /**
-     * 查询商品管理-商品信息列表查询
-     */
-    public List<MaterialVo4Unit> select(String materialParam, String standard, String model, String color, String brand, String mfrs,
-                                        String materialOther, String weight, String expiryNum, String enableSerialNumber,
-                                        String enableBatchNumber, String position, String enabled, String remark, String categoryId,
-                                        String mpList)
-            throws Exception{
-        String[] mpArr = new String[]{};
-        if(StringUtil.isNotEmpty(mpList)){
-            mpArr= mpList.split(",");
-        }
-        List<MaterialVo4Unit> list = new ArrayList<>();
-        try{
-            List<Long> idList = new ArrayList<>();
-            if(StringUtil.isNotEmpty(categoryId)){
-                idList = getListByParentId(Long.parseLong(categoryId));
-            }
-            PageUtils.startPage();
-            list= materialMapperEx.selectByConditionMaterial(materialParam, standard, model, color, brand, mfrs, materialOther, weight, expiryNum,
-                    enableSerialNumber, enableBatchNumber, position, enabled, remark, idList, mpList);
-            if (null != list && list.size()>0) {
-                Map<Long,BigDecimal> initialStockMap = getInitialStockMapByMaterialList(list);
-                Map<Long,BigDecimal> currentStockMap = getCurrentStockMapByMaterialList(list);
-                for (MaterialVo4Unit m : list) {
-                    if(fileUploadType == 2) {
-                        m.setImgSmall("small");
-                        m.setImgLarge("large");
-                    }
-                    m.setMaterialOther(getMaterialOtherByParam(mpArr, m));
-                    m.setInitialStock(initialStockMap.get(m.getId())!=null? initialStockMap.get(m.getId()): BigDecimal.ZERO);
-                    m.setBigUnitInitialStock(getBigUnitStock(m.getInitialStock(), m.getUnitId()));
-                    m.setStock(currentStockMap.get(m.getId())!=null? currentStockMap.get(m.getId()): BigDecimal.ZERO);
-                    m.setBigUnitStock(getBigUnitStock(m.getStock(), m.getUnitId()));
-                }
-            }
-        } catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
-
-    /**
-     * 新增商品信息
+     * 新增商品
      * @param obj
-     * @param request
-     * @return
-     * @throws Exception
      */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int insertMaterial(JSONObject obj, HttpServletRequest request)throws Exception {
-        Material m = JSONObject.parseObject(obj.toJSONString(), Material.class);
-        m.setEnabled(true);
-        //获取类型编码
-        String serial_no = materialCategoryService.getMaterialCategory(m.getCategoryId()).getSerialNo();
-        String sku = serial_no + DateUtils.dateTimeNow();
-        //设置系统sku
-        m.setSystemSku(sku);
-        try{
-            //添加商品
-            materialMapperEx.insertSelectiveEx(m);
-            Long mId = m.getId();
-            //添加商品拓展记录
-            materialExtendService.saveDetials(obj, obj.getString("sortList"), mId, "insert");
-            //初始库存
-            if(obj.get("stock")!=null) {
-                JSONArray stockArr = obj.getJSONArray("stock");
-                for (int i = 0; i < stockArr.size(); i++) {
-                    JSONObject jsonObj = stockArr.getJSONObject(i);
-                    if(jsonObj.get("id")!=null && jsonObj.get("initStock")!=null) {
-                        String number = jsonObj.getString("initStock");
-                        BigDecimal lowSafeStock = null;
-                        BigDecimal highSafeStock = null;
-                        if(jsonObj.get("lowSafeStock")!=null) {
-                            lowSafeStock = jsonObj.getBigDecimal("lowSafeStock");
-                        }
-                        if(jsonObj.get("highSafeStock")!=null) {
-                            highSafeStock = jsonObj.getBigDecimal("highSafeStock");
-                        }
-                        Long depotId = jsonObj.getLong("id");
-                        if(StringUtil.isNotEmpty(number) && Double.parseDouble(number)>0 || lowSafeStock!=null || highSafeStock!=null) {
-                            //设置初始库
-                            insertInitialStockByMaterialAndDepot(depotId, mId, parseBigDecimalEx(number), lowSafeStock, highSafeStock);
-                            //设置当前库
-                            insertCurrentStockByMaterialAndDepot(depotId, mId, parseBigDecimalEx(number));
-                        }
-                    }
-                }
-            }
-            logService.insertLog("商品",
-                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(m.getName()).toString(), request);
-            return 1;
-        }
-        catch (BusinessRunTimeException ex) {
-            throw new BusinessRunTimeException(ex.getCode(), ex.getMessage());
-        }
-        catch(Exception e){
-            JshException.writeFail(logger, e);
-            return 0;
-        }
-    }
+    int insertMaterial(JSONObject obj, HttpServletRequest request)throws Exception;
 
-    /**
-     * 修改商品
-     * @param obj
-     * @param request
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int updateMaterial(JSONObject obj, HttpServletRequest request) throws Exception{
-        Material material = JSONObject.parseObject(obj.toJSONString(), Material.class);
-        try{
-            //修改商品属性
-            materialMapper.updateByPrimaryKeySelective(material);
-            //
-            if(material.getUnitId() == null) {
-                materialMapperEx.setUnitIdToNull(material.getId());
-            }
-//            if(material.getExpiryNum() == null) {
-//                materialMapperEx.setExpiryNumToNull(material.getId());
-//            }
-            materialExtendService.saveDetials(obj, obj.getString("sortList"),material.getId(), "update");
-            if(obj.get("stock")!=null) {
-                JSONArray stockArr = obj.getJSONArray("stock");
-                for (int i = 0; i < stockArr.size(); i++) {
-                    JSONObject jsonObj = stockArr.getJSONObject(i);
-                    if (jsonObj.get("id") != null && jsonObj.get("initStock") != null) {
-                        String number = jsonObj.getString("initStock");
-                        BigDecimal lowSafeStock = null;
-                        BigDecimal highSafeStock = null;
-                        if(jsonObj.get("lowSafeStock")!=null) {
-                            lowSafeStock = jsonObj.getBigDecimal("lowSafeStock");
-                        }
-                        if(jsonObj.get("highSafeStock")!=null) {
-                            highSafeStock = jsonObj.getBigDecimal("highSafeStock");
-                        }
-                        Long depotId = jsonObj.getLong("id");
-                        //初始库存-先清除再插入
-                        MaterialInitialStockExample example = new MaterialInitialStockExample();
-                        example.createCriteria().andMaterialIdEqualTo(material.getId()).andDepotIdEqualTo(depotId);
-                        materialInitialStockMapper.deleteByExample(example);
-                        if (StringUtil.isNotEmpty(number) || lowSafeStock!=null || highSafeStock!=null) {
-                            insertInitialStockByMaterialAndDepot(depotId, material.getId(), parseBigDecimalEx(number), lowSafeStock, highSafeStock);
-                        }
-                        //更新当前库存
-                        depotItemService.updateCurrentStockFun(material.getId(), depotId);
-                    }
-                }
-            }
-            logService.insertLog("商品",
-                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(material.getName()).toString(), request);
-            return 1;
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-            return 0;
-        }
-    }
+    int updateMaterial(JSONObject obj, HttpServletRequest request) throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int deleteMaterial(Long id, HttpServletRequest request)throws Exception {
-        return batchDeleteMaterialByIds(id.toString());
-    }
+    int deleteMaterial(Long id, HttpServletRequest request)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int batchDeleteMaterial(String ids, HttpServletRequest request)throws Exception {
-        return batchDeleteMaterialByIds(ids);
-    }
+    int batchDeleteMaterial(String ids, HttpServletRequest request)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int batchDeleteMaterialByIds(String ids) throws Exception{
-        String [] idArray=ids.split(",");
-        //校验单据子表	jsh_depot_item
-        List<DepotItem> depotItemList =null;
-        try{
-            depotItemList=  depotItemMapperEx.getDepotItemListListByMaterialIds(idArray);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        if(depotItemList!=null&&depotItemList.size()>0){
-            logger.error("异常码[{}],异常提示[{}],参数,MaterialIds[{}]",
-                    ExceptionConstants.DELETE_FORCE_CONFIRM_CODE,ExceptionConstants.DELETE_FORCE_CONFIRM_MSG,ids);
-            throw new BusinessRunTimeException(ExceptionConstants.DELETE_FORCE_CONFIRM_CODE,
-                    ExceptionConstants.DELETE_FORCE_CONFIRM_MSG);
-        }
-        //记录日志
-        StringBuffer sb = new StringBuffer();
-        sb.append(BusinessConstants.LOG_OPERATION_TYPE_DELETE);
-        //路径列表
-        List<String> pathList = new ArrayList<>();
-        List<Material> list = getMaterialListByIds(ids);
-        for(Material material: list){
-            sb.append("[").append(material.getName()).append("]");
-            if(StringUtil.isNotEmpty(material.getImgName())) {
-                pathList.add(material.getImgName());
-            }
-        }
-        logService.insertLog("商品", sb.toString(),
-                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
-        User userInfo=userService.getCurrentUser();
-        //校验通过执行删除操作
-        try{
-            //逻辑删除商品
-            materialMapperEx.batchDeleteMaterialByIds(new Date(),userInfo==null?null:userInfo.getId(),idArray);
-            //逻辑删除商品价格扩展
-            materialExtendMapperEx.batchDeleteMaterialExtendByMIds(idArray);
-            //逻辑删除文件
-            systemConfigService.deleteFileByPathList(pathList);
-            return 1;
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-            return 0;
-        }
-    }
+    int batchDeleteMaterialByIds(String ids) throws Exception;
 
-    public int checkIsNameExist(Long id, String name)throws Exception {
-        MaterialExample example = new MaterialExample();
-        example.createCriteria().andIdNotEqualTo(id).andNameEqualTo(name).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        List<Material> list =null;
-        try{
-            list=  materialMapper.selectByExample(example);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list==null?0:list.size();
-    }
+    int checkIsNameExist(Long id, String name)throws Exception;
 
-    public int checkIsExist(Long id, String name, String model, String color, String standard, String mfrs,
-                            String otherField1, String otherField2, String otherField3, String unit, Long unitId)throws Exception {
-        return materialMapperEx.checkIsExist(id, name, model, color, standard, mfrs, otherField1,
-                otherField2, otherField3, unit, unitId);
-    }
+    int checkIsExist(Long id, String name, String model, String color, String standard, String mfrs,
+                     String otherField1, String otherField2, String otherField3, String unit, Long unitId)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int batchSetStatus(Boolean status, String ids)throws Exception {
-        logService.insertLog("商品",
-                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(ids).toString(),
-                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
-        List<Long> materialIds = StringUtil.strToLongList(ids);
-        Material material = new Material();
-        material.setEnabled(status);
-        MaterialExample example = new MaterialExample();
-        example.createCriteria().andIdIn(materialIds);
-        int result =0;
-        try{
-            result=  materialMapper.updateByExampleSelective(material, example);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    int batchSetStatus(Boolean status, String ids)throws Exception;
 
-    public Unit findUnit(Long mId)throws Exception{
-        Unit unit = new Unit();
-        try{
-            List<Unit> list = materialMapperEx.findUnitList(mId);
-            if(list!=null && list.size()>0) {
-                unit = list.get(0);
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return unit;
-    }
+    Unit findUnit(Long mId)throws Exception;
 
-    public List<MaterialVo4Unit> findById(Long id)throws Exception{
-        List<MaterialVo4Unit> list =null;
-        try{
-            list=  materialMapperEx.findById(id);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<MaterialVo4Unit> findById(Long id)throws Exception;
 
-    public List<MaterialVo4Unit> findByIdWithBarCode(Long meId)throws Exception{
-        List<MaterialVo4Unit> list =null;
-        try{
-            list=  materialMapperEx.findByIdWithBarCode(meId);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<MaterialVo4Unit> findByIdWithBarCode(Long meId)throws Exception;
 
-    /**
-     * 根据商品类型id获取子类型id集合
-     * @param parentId 商品类型父id
-     * @return
-     */
-    public List<Long> getListByParentId(Long parentId) {
-        List<Long> idList = new ArrayList<Long>();
-        List<MaterialCategory> list = materialCategoryMapperEx.getListByParentId(parentId);
-        idList.add(parentId);
-        if(list!=null && list.size()>0) {
-            getIdListByParentId(idList, parentId);
-        }
-        return idList;
-    }
+    List<Long> getListByParentId(Long parentId);
 
-    public List<Long> getIdListByParentId(List<Long> idList, Long parentId){
-        List<MaterialCategory> list = materialCategoryMapperEx.getListByParentId(parentId);
-        if(list!=null && list.size()>0) {
-            for(MaterialCategory mc : list){
-                idList.add(mc.getId());
-                getIdListByParentId(idList, mc.getId());
-            }
-        }
-        return idList;
-    }
+    List<Long> getIdListByParentId(List<Long> idList, Long parentId);
 
-    public JSONArray getMaterialByParam(String materialParam) {
-        JSONArray arr = new JSONArray();
-        List<MaterialVoSearch> list = materialMapperEx.getMaterialByParam(materialParam);
-        for(MaterialVoSearch item: list) {
-            JSONObject obj = new JSONObject();
-            StringBuilder sb = new StringBuilder();
-            sb.append(item.getBarCode());
-            sb.append("_").append(item.getName());
-            if(StringUtil.isNotEmpty(item.getMnemonic())) {
-                sb.append("(").append(item.getMnemonic()).append(")");
-            }
-            if(StringUtil.isNotEmpty(item.getStandard())) {
-                sb.append("(").append(item.getStandard()).append(")");
-            }
-            if(StringUtil.isNotEmpty(item.getModel())) {
-                sb.append("(").append(item.getModel()).append(")");
-            }
-            if(StringUtil.isNotEmpty(item.getColor())) {
-                sb.append("(").append(item.getColor()).append(")");
-            }
-            if(StringUtil.isNotEmpty(item.getUnit())) {
-                sb.append("(").append(item.getUnit()).append(")");
-            }
-            obj.put("barCode", item.getBarCode());
-            obj.put("materialStr", sb.toString());
-            arr.add(obj);
-        }
-        return arr;
-    }
+    JSONArray getMaterialByParam(String materialParam);
 
-    public List<MaterialVo4Unit> findBySelectWithBarCode(Long categoryId, String q, String standardOrModel, String color,
-                                                         String brand, String mfrs, String enableSerialNumber, String enableBatchNumber,
-                                                         Integer offset, Integer rows) throws Exception{
-        List<MaterialVo4Unit> list =null;
-        try{
-            List<Long> idList = new ArrayList<>();
-            if(categoryId!=null){
-                Long parentId = categoryId;
-                idList = getListByParentId(parentId);
-            }
-            if(StringUtil.isNotEmpty(q)) {
-                q = q.replace("'", "");
-                q = q.trim();
-            }
-            list=  materialMapperEx.findBySelectWithBarCode(idList, q, standardOrModel, color, brand, mfrs,
-                    enableSerialNumber, enableBatchNumber, offset, rows);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<MaterialVo4Unit> findBySelectWithBarCode(Long categoryId, String q, String standardOrModel, String color,
+                                                  String brand, String mfrs, String enableSerialNumber, String enableBatchNumber,
+                                                  Integer offset, Integer rows, Long depotId) throws Exception;
 
-    public int findBySelectWithBarCodeCount(Long categoryId, String q, String standardOrModel, String color,
-                                            String brand, String mfrs, String enableSerialNumber, String enableBatchNumber) throws Exception{
-        int result=0;
-        try{
-            List<Long> idList = new ArrayList<>();
-            if(categoryId!=null){
-                Long parentId = categoryId;
-                idList = getListByParentId(parentId);
-            }
-            if(StringUtil.isNotEmpty(q)) {
-                q = q.replace("'", "");
-            }
-            result = materialMapperEx.findBySelectWithBarCodeCount(idList, q, standardOrModel, color, brand, mfrs,
-                    enableSerialNumber, enableBatchNumber);
-        }catch(Exception e){
-            logger.error("异常码[{}],异常提示[{}],异常[{}]",
-                    ExceptionConstants.DATA_READ_FAIL_CODE,ExceptionConstants.DATA_READ_FAIL_MSG,e);
-            throw new BusinessRunTimeException(ExceptionConstants.DATA_READ_FAIL_CODE,
-                    ExceptionConstants.DATA_READ_FAIL_MSG);
-        }
-        return result;
-    }
+    int findBySelectWithBarCodeCount(Long categoryId, String q, String standardOrModel, String color,
+                                     String brand, String mfrs, String enableSerialNumber, String enableBatchNumber, Long depotId) throws Exception;
 
-    /**
-     * 导出商品信息
-     * @param categoryId
-     * @param materialParam
-     * @param color
-     * @param materialOther
-     * @param weight
-     * @param expiryNum
-     * @param enabled
-     * @param enableSerialNumber
-     * @param enableBatchNumber
-     * @param remark
-     * @param response
-     * @throws Exception
-     */
-    public void exportExcel(String categoryId, String materialParam, String color, String materialOther, String weight,
-                                             String expiryNum, String enabled, String enableSerialNumber, String enableBatchNumber,
-                                             String remark, HttpServletResponse response)throws Exception {
-        //查询类型子集合id
-        List<Long> idList = new ArrayList<>();
-        if(StringUtil.isNotEmpty(categoryId)){
-            idList = getListByParentId(Long.parseLong(categoryId));
-        }
-        //查询商品主条码相关列表
-        List<MaterialVo4Unit> dataList = materialMapperEx.exportExcel(materialParam, color, materialOther, weight, expiryNum, enabled, enableSerialNumber,
-                enableBatchNumber, remark, idList);
-        //查询商品副条码相关列表
-        Map<Long, MaterialExtend> otherMaterialMap = new HashMap<>();
-        List<MaterialExtend> otherDataList = materialMapperEx.getOtherMaterialList();
-        for(MaterialExtend me: otherDataList) {
-            //遇到多个副条码的情况,只加第一个
-            otherMaterialMap.putIfAbsent(me.getMaterialId(), me);
-        }
-        String nameStr = "名称*,规格,型号,颜色,品牌,类别,基础重量(kg),基本单位*,副单位,基本条码*,副条码,比例,多属性," +
-                "采购价,零售价,销售价,最低售价,状态*,序列号,批号,自定义1,自定义2,自定义3,备注,系统sku,生产日期,保质期,供应商,商品条码,批次号,仓库名称,仓位货架";
-        List<String> nameList = StringUtil.strToStringList(nameStr);
-        //仓库列表
-        List<Depot> depotList = depotService.getAllList();
-        if (nameList != null) {
-            for(Depot depot: depotList) {
-                nameList.add(depot.getName());
-            }
-        }
-        //期初库存缓存
-        List<MaterialInitialStock> misList = materialInitialStockMapperEx.getListExceptZero();
-        Map<String, BigDecimal> misMap = new HashMap<>();
-        if (misList != null) {
-            for (MaterialInitialStock mis : misList) {
-                misMap.put(mis.getMaterialId() + "_" + mis.getDepotId(), mis.getNumber());
-            }
-        }
-        String[] names = StringUtil.listToStringArray(nameList);
-        String title = "商品信息";
-        List<String[]> objects = new ArrayList<>();
-        if (null != dataList) {
-            for (MaterialVo4Unit m : dataList) {
-                String[] objs = new String[names.length];
-                objs[0] = m.getName();
-                objs[1] = m.getStandard();
-                objs[2] = m.getModel();
-                objs[3] = m.getColor();
-                objs[4] = m.getBrand();
-                objs[5] = m.getCategoryName();
-                objs[6] = m.getWeight() == null ? "" : m.getWeight().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
-                objs[7] = m.getCommodityUnit();
-                objs[8] = otherMaterialMap.get(m.getId()) == null ? "" : otherMaterialMap.get(m.getId()).getCommodityUnit();
-                objs[9] = m.getmBarCode();
-                objs[10] = otherMaterialMap.get(m.getId()) == null ? "" : otherMaterialMap.get(m.getId()).getBarCode();
-                objs[11] = m.getRatio() == null ? "" : m.getRatio().toString();
-                objs[12] = m.getSku();
-                objs[13] = m.getPurchaseDecimal() == null ? "" : m.getPurchaseDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
-                objs[14] = m.getCommodityDecimal() == null ? "" : m.getCommodityDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
-                objs[15] = m.getWholesaleDecimal() == null ? "" : m.getWholesaleDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
-                objs[16] = m.getLowDecimal() == null ? "" : m.getLowDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
-                objs[17] = m.getEnabled() ? "1" : "0";
-                objs[18] = m.getEnableSerialNumber();
-                objs[19] = m.getEnableBatchNumber();
-                objs[20] = m.getOtherField1();
-                objs[21] = m.getOtherField2();
-                objs[22] = m.getOtherField3();
-                objs[23] = m.getRemark();
-                objs[24] = m.getSystemSku();
-                objs[25] = m.getProductionDate() == null ? "" : m.getProductionDate().toString();
-                objs[26] = m.getExpiryNum() == null ? "" : m.getExpiryNum().toString();
-                objs[27] = m.getSupplierId() == null ? "" : m.getSupplierId().toString();
-                objs[28] = m.getBarCode();
-                objs[29] = m.getBatchNumber();
-                objs[30] = m.getDepotId() == null ? "" : m.getDepotId().toString();
-                objs[31] = m.getPosition();
-                //仓库期初库存
-                int i = 32;
-                for(Depot depot: depotList) {
-                    BigDecimal number = misMap.get(m.getId() + "_" + depot.getId());
-                    objs[i] = number == null ? "0" : number.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
-                    i++;
-                }
-                objects.add(objs);
-            }
-        }
-        File file = ExcelUtils.exportObjectsOneSheet(title, "*导入时本行内容请勿删除,切记!", names, title, objects);
-        ExcelUtils.downloadExcel(file, file.getName(), response);
-    }
+    void exportExcel(String categoryId, String materialParam, String color, String materialOther, String weight,
+                     String expiryNum, String enabled, String enableSerialNumber, String enableBatchNumber,
+                     String remark, HttpServletResponse response)throws Exception;
 
-    /**
-     * 导入商品信息
-     * @param file
-     * @param request
-     * @return
-     * @throws Exception
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public BaseResponseInfo importExcel(MultipartFile file, HttpServletRequest request) throws Exception {
-        BaseResponseInfo info = new BaseResponseInfo();
-        try {
-            Long beginTime = System.currentTimeMillis();
-            //文件扩展名只能为xls
-            String fileName = file.getOriginalFilename();
-            if(StringUtil.isNotEmpty(fileName)) {
-                String fileExt = fileName.substring(fileName.indexOf(".")+1);
-                if(!"xls".equals(fileExt)) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXTENSION_ERROR_CODE,
-                            ExceptionConstants.MATERIAL_EXTENSION_ERROR_MSG);
-                }
-            }
-            Workbook workbook = Workbook.getWorkbook(file.getInputStream());
-            Sheet src = workbook.getSheet(0);
-            //获取真实的行数,剔除掉空白行
-            int rightRows = ExcelUtils.getRightRows(src);
-            List<Depot> depotList= depotService.getDepot();
-            int depotCount = depotList.size();
-            Map<String, Long> depotMap = parseDepotToMap(depotList);
-            User user = userService.getCurrentUser();
-            List<MaterialWithInitStock> mList = new ArrayList<>();
-            //单次导入超出1000条
-            if(rightRows > 1002) {
-                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_IMPORT_OVER_LIMIT_CODE,
-                        String.format(ExceptionConstants.MATERIAL_IMPORT_OVER_LIMIT_MSG));
-            }
-            for (int i = 2; i < rightRows; i++) {
-                String name = ExcelUtils.getContent(src, i, 0); //名称
-                String standard = ExcelUtils.getContent(src, i, 1); //规格
-                String model = ExcelUtils.getContent(src, i, 2); //型号
-                String color = ExcelUtils.getContent(src, i, 3); //颜色
-                String brand = ExcelUtils.getContent(src, i, 4); //品牌
-                String categoryName = ExcelUtils.getContent(src, i, 5); //类别
-                String weight = ExcelUtils.getContent(src, i, 6); //基础重量(kg)
-                String expiryNum = ExcelUtils.getContent(src, i, 7); //保质期(天)
-                String unit = ExcelUtils.getContent(src, i, 8); //基本单位
-                //名称为空
-                if(StringUtil.isEmpty(name)) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_EMPTY_CODE,
-                            String.format(ExceptionConstants.MATERIAL_NAME_EMPTY_MSG, i+1));
-                }
-                //名称长度超出
-                if(name.length()>100) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_OVER_CODE,
-                            String.format(ExceptionConstants.MATERIAL_NAME_OVER_MSG, i+1));
-                }
-                //规格长度超出
-                if(StringUtil.isNotEmpty(standard) && standard.length()>100) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STANDARD_OVER_CODE,
-                            String.format(ExceptionConstants.MATERIAL_STANDARD_OVER_MSG, i+1));
-                }
-                //型号长度超出
-                if(StringUtil.isNotEmpty(model) && model.length()>100) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_MODEL_OVER_CODE,
-                            String.format(ExceptionConstants.MATERIAL_MODEL_OVER_MSG, i+1));
-                }
-                //基本单位为空
-                if(StringUtil.isEmpty(unit)) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_UNIT_EMPTY_CODE,
-                            String.format(ExceptionConstants.MATERIAL_UNIT_EMPTY_MSG, i+1));
-                }
-                //列别为空
-                if(StringUtil.isEmpty(categoryName)) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_Category_Name_EMPTY_CODE,
-                            String.format(ExceptionConstants.MATERIAL_Category_Name_EMPTY_MSG, i+1));
-                }
-                MaterialWithInitStock m = new MaterialWithInitStock();
-                m.setName(name);
-                m.setStandard(standard);
-                m.setModel(model);
-                m.setColor(color);
-                m.setBrand(brand);
-                //通过名称生成助记码
-                m.setMnemonic(PinYinUtil.getFirstLettersLo(name));
-                Long categoryId = materialCategoryService.getCategoryIdByName(categoryName);
-                //获取类型编码
-                String serial_no = categoryId == null ? null : materialCategoryService.getMaterialCategory(m.getCategoryId()).getSerialNo();
-                //设置系统sku
-                m.setSystemSku(serial_no + DateUtils.dateTimeNow());
-                if(null!=categoryId){
-                    m.setCategoryId(categoryId);
-                }
-                if(StringUtil.isNotEmpty(weight)) {
-                    //校验基础重量是否是数字(含小数)
-                    if(!StringUtil.isPositiveBigDecimal(weight)) {
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_WEIGHT_NOT_DECIMAL_CODE,
-                                String.format(ExceptionConstants.MATERIAL_WEIGHT_NOT_DECIMAL_MSG, i+1));
-                    }
-                    m.setWeight(new BigDecimal(weight));
-                }
-                if(StringUtil.isNotEmpty(expiryNum)) {
-                    //校验保质期是否是正整数
-                    if(!StringUtil.isPositiveLong(expiryNum)) {
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXPIRY_NUM_NOT_INTEGER_CODE,
-                                String.format(ExceptionConstants.MATERIAL_EXPIRY_NUM_NOT_INTEGER_MSG, i+1));
-                    }
-                    //m.setExpiryNum(Integer.parseInt(expiryNum));
-                }
-                String manyUnit = ExcelUtils.getContent(src, i, 9); //副单位
-                String barCode = ExcelUtils.getContent(src, i, 10); //基础条码
-                String manyBarCode = ExcelUtils.getContent(src, i, 11); //副条码
-                String ratio = ExcelUtils.getContent(src, i, 12); //比例
-                String sku = ExcelUtils.getContent(src, i, 13); //多属性
-                String purchaseDecimal = ExcelUtils.getContent(src, i, 14); //采购价
-                String commodityDecimal = ExcelUtils.getContent(src, i, 15); //零售价
-                String wholesaleDecimal = ExcelUtils.getContent(src, i, 16); //销售价
-                String lowDecimal = ExcelUtils.getContent(src, i, 17); //最低售价
-                String enabled = ExcelUtils.getContent(src, i, 18); //状态
-                String enableSerialNumber = ExcelUtils.getContent(src, i, 19); //序列号
-                String enableBatchNumber = ExcelUtils.getContent(src, i, 20); //批号
-                String position = ExcelUtils.getContent(src, i, 21); //仓位货架
-                String mfrs = ExcelUtils.getContent(src, i, 22); //制造商
-                String otherField1 = ExcelUtils.getContent(src, i, 23); //自定义1
-                String otherField2 = ExcelUtils.getContent(src, i, 24); //自定义2
-                String otherField3 = ExcelUtils.getContent(src, i, 25); //自定义3
-                String remark = ExcelUtils.getContent(src, i, 26); //备注
-               // m.setPosition(StringUtil.isNotEmpty(position)?position:null);
-                //m.setMfrs(StringUtil.isNotEmpty(mfrs)?mfrs:null);
-                m.setOtherField1(StringUtil.isNotEmpty(otherField1)?otherField1:null);
-                m.setOtherField2(StringUtil.isNotEmpty(otherField2)?otherField2:null);
-                m.setOtherField3(StringUtil.isNotEmpty(otherField3)?otherField3:null);
-                m.setRemark(remark);
-                //状态格式错误
-                if(!"1".equals(enabled) && !"0".equals(enabled)) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ENABLED_ERROR_CODE,
-                            String.format(ExceptionConstants.MATERIAL_ENABLED_ERROR_MSG, i+1));
-                }
-                //基本条码为空
-                if(StringUtil.isEmpty(barCode)) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_EMPTY_CODE,
-                            String.format(ExceptionConstants.MATERIAL_BARCODE_EMPTY_MSG, i+1));
-                }
-                //校验基本条码长度为4到40位
-                if(!StringUtil.checkBarCodeLength(barCode)) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_CODE,
-                            String.format(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_MSG, barCode));
-                }
-                //校验副条码长度为4到40位
-                if(StringUtil.isNotEmpty(manyBarCode) && !StringUtil.checkBarCodeLength(manyBarCode)) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_CODE,
-                            String.format(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_MSG, manyBarCode));
-                }
-                //批量校验excel中有无重复商品,是指名称、规格、型号、颜色、单位、多属性
-                batchCheckExistMaterialListByParam(mList, name, standard, model, color, unit, sku);
-                //批量校验excel中有无重复条码(1-文档自身校验,2-和数据库里面的商品校验)
-                batchCheckExistBarCodeByParam(mList, barCode, manyBarCode);
-                //设置商品拓展属性
-                JSONObject materialExObj = new JSONObject();
-                JSONObject basicObj = new JSONObject();
-                basicObj.put("barCode", barCode);
-                basicObj.put("commodityUnit", unit);
-                basicObj.put("sku", sku);
-                basicObj.put("purchaseDecimal", purchaseDecimal);
-                basicObj.put("commodityDecimal", commodityDecimal);
-                basicObj.put("wholesaleDecimal", wholesaleDecimal);
-                basicObj.put("lowDecimal", lowDecimal);
-                materialExObj.put("basic", basicObj);
-                if(StringUtil.isNotEmpty(manyUnit) && StringUtil.isNotEmpty(ratio)){ //多单位
-                    //校验比例是否是数字(含小数)
-                    if(!StringUtil.isPositiveBigDecimal(ratio.trim())) {
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_RATIO_NOT_INTEGER_CODE,
-                                String.format(ExceptionConstants.MATERIAL_RATIO_NOT_INTEGER_MSG, i+1));
-                    }
-                    Long unitId = unitService.getUnitIdByParam(unit, manyUnit, new BigDecimal(ratio.trim()));
-                    if(unitId != null) {
-                        m.setUnitId(unitId);
-                        m.setUnit("");
-                    } else {
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_UNIT_MATE_CODE,
-                                String.format(ExceptionConstants.MATERIAL_UNIT_MATE_MSG, manyBarCode));
-                    }
-                    JSONObject otherObj = new JSONObject();
-                    otherObj.put("barCode", manyBarCode);
-                    otherObj.put("commodityUnit", manyUnit);
-                    otherObj.put("purchaseDecimal", parsePrice(purchaseDecimal,ratio));
-                    otherObj.put("commodityDecimal", parsePrice(commodityDecimal,ratio));
-                    otherObj.put("wholesaleDecimal", parsePrice(wholesaleDecimal,ratio));
-                    otherObj.put("lowDecimal", parsePrice(lowDecimal,ratio));
-                    materialExObj.put("other", otherObj);
-                } else {
-                    m.setUnit(unit);
-                    m.setUnitId(null);
-                }
-                m.setMaterialExObj(materialExObj);
-                m.setEnabled("1".equals(enabled));
-                if(StringUtil.isNotEmpty(enableSerialNumber) && "1".equals(enableSerialNumber)) {
-                    m.setEnableSerialNumber("1");
-                } else {
-                    m.setEnableSerialNumber("0");
-                }
-                if(StringUtil.isNotEmpty(enableBatchNumber) && "1".equals(enableBatchNumber)) {
-                    m.setEnableBatchNumber("1");
-                } else {
-                    m.setEnableBatchNumber("0");
-                }
-                if("1".equals(enableSerialNumber) && "1".equals(enableBatchNumber)) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ENABLE_MUST_ONE_CODE,
-                            String.format(ExceptionConstants.MATERIAL_ENABLE_MUST_ONE_MSG, barCode));
-                }
-                m.setStockMap(getStockMapCache(src, depotCount, depotMap, i));
-                mList.add(m);
-            }
-            List<Long> deleteInitialStockMaterialIdList = new ArrayList<>();
-            List<Long> deleteCurrentStockMaterialIdList = new ArrayList<>();
-            List<MaterialInitialStock> insertInitialStockMaterialList = new ArrayList<>();
-            List<MaterialCurrentStock> insertCurrentStockMaterialList = new ArrayList<>();
-            //防止初始库存和当前库存出现重复
-            Map<String, String> materialDepotInitialMap = new HashMap<>();
-            Map<String, String> materialDepotCurrentMap = new HashMap<>();
-            for(MaterialWithInitStock m: mList) {
-                Long mId = 0L;
-                //判断该商品是否存在,如果不存在就新增,如果存在就更新
-                String basicBarCode = getBasicBarCode(m);
-                //根据条件返回产品列表
-                List<Material> materials = getMaterialListByParam(m.getName(),m.getStandard(),m.getModel(),m.getColor(),m.getUnit(),m.getUnitId(), basicBarCode);
-                if(materials.size() == 0) { //产品列表为0,新增商品
-                    materialMapperEx.insertSelectiveEx(m);
-                    mId = m.getId();
-                } else { //产品列表不为0,商品存在,修改商品属性
-                    mId = materials.get(0).getId();
-                    String materialJson = JSON.toJSONString(m);
-                    Material material = JSONObject.parseObject(materialJson, Material.class);
-                    material.setId(mId);
-                    materialMapper.updateByPrimaryKeySelective(material);
-                    //更新多单位
-                    if(material.getUnitId() == null) {
-                        materialMapperEx.setUnitIdToNull(material.getId());
-                    }
-                    //如果之前有保质期,则更新保质期
-//                    if(materials.get(0).getExpiryNum()!=null && material.getExpiryNum() == null) {
-//                        materialMapperEx.setExpiryNumToNull(material.getId());
-//                    }
-                }
-                //给商品新增或更新条码与价格相关信息
-                JSONObject materialExObj = m.getMaterialExObj();
-                insertOrUpdateMaterialExtend(materialExObj, "basic", "1", mId, user);
-                insertOrUpdateMaterialExtend(materialExObj, "other", "0", mId, user);
-                //给商品更新库存
-                Map<Long, BigDecimal> stockMap = m.getStockMap();
-                for(Depot depot: depotList){
-                    Long depotId = depot.getId();
-                    String materialDepotKey = mId + "_" + depotId;
-                    //获取初始库存
-                    BigDecimal initStock = getInitStock(mId, depotId);
-                    //excel里面的当前库存
-                    BigDecimal stock = stockMap.get(depot.getId());
-                    //新增或更新初始库存
-                    if(stock!=null && stock.compareTo(BigDecimal.ZERO)!=0) {
-                        String basicStr = materialExObj.getString("basic");
-                        MaterialExtend materialExtend = JSONObject.parseObject(basicStr, MaterialExtend.class);
-                        if(StringUtil.isNotEmpty(materialExtend.getSku())) {
-                            throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_SKU_BEGIN_STOCK_FAILED_CODE,
-                                    String.format(ExceptionConstants.MATERIAL_SKU_BEGIN_STOCK_FAILED_MSG, materialExtend.getBarCode()));
-                        }
-                        buildChangeInitialStock(deleteInitialStockMaterialIdList, insertInitialStockMaterialList, materialDepotInitialMap, mId, depotId, materialDepotKey, stock);
-                    } else {
-                        if(initStock.compareTo(BigDecimal.ZERO)!=0) {
-                            buildChangeInitialStock(deleteInitialStockMaterialIdList, insertInitialStockMaterialList, materialDepotInitialMap, mId, depotId, materialDepotKey, stock);
-                        }
-                    }
-                    //新增或更新当前库存
-                    Long billCount = depotItemService.getCountByMaterialAndDepot(mId, depotId);
-                    if(billCount == 0) {
-                        if(stock!=null && stock.compareTo(BigDecimal.ZERO)!=0) {
-                            buildChangeCurrentStock(deleteCurrentStockMaterialIdList, insertCurrentStockMaterialList, materialDepotCurrentMap, mId, depotId, materialDepotKey, stock);
-                        } else {
-                            if(initStock.compareTo(BigDecimal.ZERO)!=0) {
-                                buildChangeCurrentStock(deleteCurrentStockMaterialIdList, insertCurrentStockMaterialList, materialDepotCurrentMap, mId, depotId, materialDepotKey, stock);
-                            }
-                        }
-                    } else {
-                        BigDecimal currentNumber = getCurrentStockByMaterialIdAndDepotId(mId, depotId);
-                        //当前库存的更新:减去初始库存,再加上导入的新初始库存
-                        if(currentNumber!=null && initStock!=null && stock!=null) {
-                            currentNumber = currentNumber.subtract(initStock).add(stock);
-                        }
-                        buildChangeCurrentStock(deleteCurrentStockMaterialIdList, insertCurrentStockMaterialList, materialDepotCurrentMap, mId, depotId, materialDepotKey, currentNumber);
-                    }
-                }
-            }
-            //批量更新库存,先删除后新增
-            if(insertInitialStockMaterialList.size()>0) {
-                batchDeleteInitialStockByMaterialList(deleteInitialStockMaterialIdList);
-                materialInitialStockMapperEx.batchInsert(insertInitialStockMaterialList);
-            }
-            if(insertCurrentStockMaterialList.size()>0) {
-                batchDeleteCurrentStockByMaterialList(deleteCurrentStockMaterialIdList);
-                materialCurrentStockMapperEx.batchInsert(insertCurrentStockMaterialList);
-            }
-            //添加日志
-            logService.insertLog("商品",
-                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_IMPORT).append(mList.size()).append(BusinessConstants.LOG_DATA_UNIT).toString(),
-                    ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
-            Long endTime = System.currentTimeMillis();
-            logger.info("导入耗时:{}", endTime-beginTime);
-            info.code = 200;
-            info.data = "导入成功";
-        } catch (BusinessRunTimeException e) {
-            info.code = e.getCode();
-            info.data = e.getData().get("message");
-        } catch (Exception e) {
-            logger.error(e.getMessage(), e);
-            info.code = 500;
-            info.data = "导入失败";
-        }
-        return info;
-    }
-
-    /**
-     * 构造初始库存的变化
-     */
-    private void buildChangeInitialStock(List<Long> deleteInitialStockMaterialIdList, List<MaterialInitialStock> insertInitialStockMaterialList,
-                                         Map<String, String> materialDepotInitialMap, Long mId, Long depotId, String materialDepotKey, BigDecimal stock) {
-        if(materialDepotInitialMap.get(materialDepotKey)==null) {
-            MaterialInitialStock materialInitialStock = new MaterialInitialStock();
-            materialInitialStock.setMaterialId(mId);
-            materialInitialStock.setDepotId(depotId);
-            materialInitialStock.setNumber(stock);
-            insertInitialStockMaterialList.add(materialInitialStock);
-            deleteInitialStockMaterialIdList.add(mId);
-            materialDepotInitialMap.put(materialDepotKey, materialDepotKey);
-        }
-    }
+    BaseResponseInfo importExcel(MultipartFile file, HttpServletRequest request) throws Exception;
 
-    /**
-     * 构造当前库存的变化
-     */
-    private void buildChangeCurrentStock(List<Long> deleteCurrentStockMaterialIdList, List<MaterialCurrentStock> insertCurrentStockMaterialList,
-                                         Map<String, String> materialDepotCurrentMap, Long mId, Long depotId, String materialDepotKey, BigDecimal stock) {
-        if(materialDepotCurrentMap.get(materialDepotKey)==null) {
-            MaterialCurrentStock materialCurrentStock = new MaterialCurrentStock();
-            materialCurrentStock.setMaterialId(mId);
-            materialCurrentStock.setDepotId(depotId);
-            materialCurrentStock.setCurrentNumber(stock);
-            insertCurrentStockMaterialList.add(materialCurrentStock);
-            deleteCurrentStockMaterialIdList.add(mId);
-            materialDepotCurrentMap.put(materialDepotKey, materialDepotKey);
-        }
-    }
+    void batchCheckExistMaterialListByParam(List<MaterialWithInitStock> mList, String name, String standard,
+                                            String model, String color, String unit, String sku);
 
-    private Map<String, Long> parseDepotToMap(List<Depot> depotList) {
-        Map<String, Long> map = new HashMap<>();
-        for(Depot depot: depotList) {
-            map.put(depot.getName(), depot.getId());
-        }
-        return map;
-    }
+    void batchCheckExistBarCodeByParam(List<MaterialWithInitStock> mList,
+                                       String barCode, String manyBarCode) throws Exception;
 
-    /**
-     * 缓存各个仓库的库存信息
-     * @param src
-     * @param depotCount
-     * @param depotMap
-     * @param i
-     * @return
-     * @throws Exception
-     */
-    private Map<Long, BigDecimal> getStockMapCache(Sheet src, int depotCount, Map<String, Long> depotMap, int i) throws Exception {
-        Map<Long, BigDecimal> stockMap = new HashMap<>();
-        for(int j = 1; j<= depotCount; j++) {
-            int col = 26 + j;
-            if(col < src.getColumns()){
-                String depotName = ExcelUtils.getContent(src, 1, col); //获取仓库名称
-                if(StringUtil.isNotEmpty(depotName)) {
-                    Long depotId = depotMap.get(depotName);
-                    if(depotId!=null && depotId!=0L){
-                        String stockStr = ExcelUtils.getContent(src, i, col);
-                        if(StringUtil.isNotEmpty(stockStr)) {
-                            stockMap.put(depotId, parseBigDecimalEx(stockStr));
-                        }
-                    }
-                }
-            }
-        }
-        return stockMap;
-    }
-
-    /**
-     * 批量校验excel中有无重复商品,是指名称、规格、型号、颜色、单位
-     * @param mList
-     */
-    public void batchCheckExistMaterialListByParam(List<MaterialWithInitStock> mList, String name, String standard,
-                                                   String model, String color, String unit, String sku) {
-        for(MaterialWithInitStock material: mList){
-            String materialSku = "";
-            JSONObject materialExObj = material.getMaterialExObj();
-            if(materialExObj!=null && materialExObj.get("basic")!=null) {
-                JSONObject basicObj = materialExObj.getJSONObject("basic");
-                if(basicObj!=null && materialExObj.get("sku")!=null) {
-                    materialSku = basicObj.getString("sku");
-                }
-            }
-            if(name.equals(material.getName()) &&
-                    standard.equals(material.getStandard()) &&
-                    model.equals(material.getModel()) &&
-                    color.equals(material.getColor()) &&
-                    unit.equals(material.getUnit()) &&
-                    sku.equals(materialSku)) {
-                String info = name + "-" + standard + "-" + model + "-" + color + "-" + unit + "-" + sku;
-                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_EXIST_CODE,
-                        String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_EXIST_MSG, info));
-            }
-        }
-    }
-
-    /**
-     * 批量校验excel中有无重复条码(1-文档自身校验,2-和数据库里面的商品校验)
-     * @param mList
-     */
-    public void batchCheckExistBarCodeByParam(List<MaterialWithInitStock> mList,
-                                              String barCode, String manyBarCode) throws Exception {
-        if(StringUtil.isNotEmpty(manyBarCode)) {
-            if(barCode.equals(manyBarCode)) {
-                //同一个商品的主副条码重复了,进行提醒
-                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_CODE,
-                        String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_MSG, manyBarCode));
-            }
-            //EXCEL中有副条码在系统中已存在(除自身商品之外)
-            int count = materialExtendService.getCountByManyBarCodeWithoutUs(manyBarCode, barCode);
-            if (count>0) {
-                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_MANY_BARCODE_EXIST_CODE,
-                        String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_MANY_BARCODE_EXIST_MSG, manyBarCode));
-            }
-        }
-        for(MaterialWithInitStock material: mList){
-            JSONObject materialExObj = material.getMaterialExObj();
-            String basicBarCode = "";
-            String otherBarCode = "";
-            if(materialExObj.get("basic")!=null) {
-                JSONObject basicObj = materialExObj.getJSONObject("basic");
-                basicBarCode = basicObj.getString("barCode");
-            }
-            if(materialExObj.get("other")!=null) {
-                JSONObject otherObj = materialExObj.getJSONObject("other");
-                otherBarCode = otherObj.getString("barCode");
-            }
-            if(barCode.equals(basicBarCode) || barCode.equals(otherBarCode)){
-                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_CODE,
-                        String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_MSG, barCode));
-            }
-            if(StringUtil.isNotEmpty(manyBarCode)) {
-                if(manyBarCode.equals(basicBarCode) || manyBarCode.equals(otherBarCode)){
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_CODE,
-                            String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_MSG, manyBarCode));
-                }
-            }
-        }
-    }
-    /**
-     * 给商品新增或更新条码与价格相关信息
-     * @param materialExObj
-     * @param type
-     * @param defaultFlag
-     * @param mId
-     * @param user
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void insertOrUpdateMaterialExtend(JSONObject materialExObj, String type, String defaultFlag, Long mId, User user) throws Exception {
-        if(StringUtil.isExist(materialExObj.get(type))){
-            //获取对应的商品拓展字符
-            String basicStr = materialExObj.getString(type);
-            MaterialExtend materialExtend = JSONObject.parseObject(basicStr, MaterialExtend.class);
-            materialExtend.setMaterialId(mId);
-            materialExtend.setDefaultFlag(defaultFlag);
-            materialExtend.setCreateTime(new Date());
-            materialExtend.setUpdateTime(System.currentTimeMillis());
-            materialExtend.setCreateSerial(user.getLoginName());
-            materialExtend.setUpdateSerial(user.getLoginName());
-            Long meId = 0L;
-            if(StringUtil.isNotEmpty(materialExtend.getSku())){
-                //含sku的商品,特殊逻辑
-                meId = materialExtendService.selectIdByMaterialIdAndBarCode(mId, materialExtend.getBarCode());
-                List<MaterialExtend> meList = materialExtendService.getListByMaterialIdAndDefaultFlagAndBarCode(mId, "1", materialExtend.getBarCode());
-                if(meList.size() == 0) {
-                    materialExtend.setDefaultFlag("1");
-                } else {
-                    materialExtend.setDefaultFlag("0");
-                }
-            } else {
-                meId = materialExtendService.selectIdByMaterialIdAndDefaultFlag(mId, defaultFlag);
-            }
-            if(meId==0L){
-                materialExtendMapper.insertSelective(materialExtend);
-            } else {
-                materialExtend.setId(meId);
-                materialExtendMapper.updateByPrimaryKeySelective(materialExtend);
-                //如果金额为空,此处单独置空
-                materialExtendMapperEx.specialUpdatePrice(materialExtend);
-            }
-        }
-    }
+    void insertOrUpdateMaterialExtend(JSONObject materialExObj, String type, String defaultFlag, Long mId, User user) throws Exception;
 
-    public String getBasicBarCode(MaterialWithInitStock m) {
-        String barCode = "";
-        JSONObject materialExObj = m.getMaterialExObj();
-        if(StringUtil.isExist(materialExObj.get("basic"))) {
-            String basicStr = materialExObj.getString("basic");
-            MaterialExtend basicMaterialExtend = JSONObject.parseObject(basicStr, MaterialExtend.class);
-            barCode = basicMaterialExtend.getBarCode();
-        }
-        return barCode;
-    }
+    String getBasicBarCode(MaterialWithInitStock m);
 
-    /**
-     * 根据条件返回产品列表
-     * @param name
-     * @param standard
-     * @param model
-     * @param color
-     * @param unit
-     * @param unitId
-     * @return
-     */
-    private List<Material> getMaterialListByParam(String name, String standard, String model, String color, String unit, Long unitId, String basicBarCode) throws Exception {
-        List<Material> list = new ArrayList<>();
-        MaterialExample example = new MaterialExample();
-        MaterialExample.Criteria criteria = example.createCriteria();
-        criteria.andNameEqualTo(name);
-        if (StringUtil.isNotEmpty(model)) {
-            criteria.andModelEqualTo(model);
-        }
-        if (StringUtil.isNotEmpty(color)) {
-            criteria.andColorEqualTo(color);
-        }
-        if (StringUtil.isNotEmpty(standard)) {
-            criteria.andStandardEqualTo(standard);
-        }
-        if (StringUtil.isNotEmpty(unit)) {
-            criteria.andUnitEqualTo(unit);
-        }
-        if (unitId !=null) {
-            criteria.andUnitIdEqualTo(unitId);
-        }
-        criteria.andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        list = materialMapper.selectByExample(example);
-        if(list.size()==0) {
-            //如果通过组合条件没有查到该商品,则通过条码再查一次
-            MaterialExtend materialExtend = materialExtendService.getInfoByBarCode(basicBarCode);
-            if(materialExtend != null && materialExtend.getMaterialId()!=null) {
-                Material material = new Material();
-                material.setId(materialExtend.getMaterialId());
-                list.add(material);
-            }
-        }
-        return list;
-    }
+    List<Material> getMaterialListByParam(String name, String standard, String model, String color, String unit, Long unitId, String basicBarCode) throws Exception;
 
-    /**
-     * 写入初始库存
-     * @param depotId
-     * @param mId
-     * @param stock
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void insertInitialStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock, BigDecimal lowSafeStock, BigDecimal highSafeStock){
-        MaterialInitialStock materialInitialStock = new MaterialInitialStock();
-        materialInitialStock.setDepotId(depotId);
-        materialInitialStock.setMaterialId(mId);
-        stock = stock == null? BigDecimal.ZERO: stock;
-        materialInitialStock.setNumber(stock);
-        if(lowSafeStock!=null) {
-            materialInitialStock.setLowSafeStock(lowSafeStock);
-        }
-        if(highSafeStock!=null) {
-            materialInitialStock.setHighSafeStock(highSafeStock);
-        }
-        materialInitialStockMapper.insertSelective(materialInitialStock); //存入初始库存
-    }
+    void insertInitialStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock, BigDecimal lowSafeStock, BigDecimal highSafeStock);
 
-    /**
-     * 写入当前库存
-     * @param depotId
-     * @param mId
-     * @param stock
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void insertCurrentStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock){
-        MaterialCurrentStock materialCurrentStock = new MaterialCurrentStock();
-        materialCurrentStock.setDepotId(depotId);
-        materialCurrentStock.setMaterialId(mId);
-        materialCurrentStock.setCurrentNumber(stock);
-        materialCurrentStockMapper.insertSelective(materialCurrentStock); //存入初始库存
-    }
+    void insertCurrentStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock);
 
-    /**
-     * 批量删除初始库存
-     * @param mIdList
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void batchDeleteInitialStockByMaterialList(List<Long> mIdList){
-        MaterialInitialStockExample example = new MaterialInitialStockExample();
-        example.createCriteria().andMaterialIdIn(mIdList);
-        materialInitialStockMapper.deleteByExample(example);
-    }
+    void batchDeleteInitialStockByMaterialList(List<Long> mIdList);
 
-    /**
-     * 批量删除当前库存
-     * @param mIdList
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void batchDeleteCurrentStockByMaterialList(List<Long> mIdList){
-        MaterialCurrentStockExample example = new MaterialCurrentStockExample();
-        example.createCriteria().andMaterialIdIn(mIdList);
-        materialCurrentStockMapper.deleteByExample(example);
-    }
+    void batchDeleteCurrentStockByMaterialList(List<Long> mIdList);
 
-    public List<MaterialVo4Unit> getMaterialEnableSerialNumberList(String q, Integer offset, Integer rows)throws Exception {
-        List<MaterialVo4Unit> list =null;
-        try{
-            list=  materialMapperEx.getMaterialEnableSerialNumberList(q, offset, rows);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<MaterialVo4Unit> getMaterialEnableSerialNumberList(String q, Integer offset, Integer rows)throws Exception;
 
-    public Long getMaterialEnableSerialNumberCount(String q)throws Exception {
-        Long count =null;
-        try{
-            count=  materialMapperEx.getMaterialEnableSerialNumberCount(q);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return count;
-    }
+    Long getMaterialEnableSerialNumberCount(String q)throws Exception;
 
-    public BigDecimal parseBigDecimalEx(String str) throws Exception{
-        if(!StringUtil.isEmpty(str)) {
-            return  new BigDecimal(str);
-        } else {
-            return null;
-        }
-    }
+    BigDecimal parseBigDecimalEx(String str) throws Exception;
 
-    public BigDecimal parsePrice(String price, String ratio) throws Exception{
-        if(StringUtil.isEmpty(price) || StringUtil.isEmpty(ratio)) {
-            return BigDecimal.ZERO;
-        } else {
-            BigDecimal pr=new BigDecimal(price);
-            BigDecimal r=new BigDecimal(ratio);
-            return pr.multiply(r);
-        }
-    }
+    BigDecimal parsePrice(String price, String ratio) throws Exception;
 
-    /**
-     * 根据商品获取初始库存-多仓库
-     * @param depotList
-     * @param materialId
-     * @return
-     */
-    public BigDecimal getInitStockByMidAndDepotList(List<Long> depotList, Long materialId) {
-        BigDecimal stock = BigDecimal.ZERO;
-        MaterialInitialStockExample example = new MaterialInitialStockExample();
-        if(depotList!=null && depotList.size()>0) {
-            example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdIn(depotList)
-                    .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        } else {
-            example.createCriteria().andMaterialIdEqualTo(materialId)
-                    .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        }
-        List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
-        if(list!=null && list.size()>0) {
-            for(MaterialInitialStock ms: list) {
-                if(ms!=null) {
-                    stock = stock.add(ms.getNumber());
-                }
-            }
-        }
-        return stock;
-    }
+    BigDecimal getInitStockByMidAndDepotList(List<Long> depotList, Long materialId);
 
-    /**
-     * 根据商品和仓库获取初始库存
-     * @param materialId
-     * @param depotId
-     * @return
-     */
-    public BigDecimal getInitStock(Long materialId, Long depotId) {
-        BigDecimal stock = BigDecimal.ZERO;
-        MaterialInitialStockExample example = new MaterialInitialStockExample();
-        example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdEqualTo(depotId)
-                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
-        if(list!=null && list.size()>0) {
-            stock = list.get(0).getNumber();
-        }
-        return stock;
-    }
+    BigDecimal getInitStock(Long materialId, Long depotId);
 
-    /**
-     * 根据商品和仓库获取当前库存
-     * @param materialId
-     * @param depotId
-     * @return
-     */
-    public BigDecimal getCurrentStockByMaterialIdAndDepotId(Long materialId, Long depotId) {
-        BigDecimal stock = BigDecimal.ZERO;
-        MaterialCurrentStockExample example = new MaterialCurrentStockExample();
-        example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdEqualTo(depotId)
-                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        List<MaterialCurrentStock> list = materialCurrentStockMapper.selectByExample(example);
-        if(list!=null && list.size()>0) {
-            stock = list.get(0).getCurrentNumber();
-        } else {
-            stock = getInitStock(materialId,depotId);
-        }
-        return stock;
-    }
+    BigDecimal getCurrentStockByMaterialIdAndDepotId(Long materialId, Long depotId);
 
-    /**
-     * 根据商品列表获取初始库存Map
-     * @param list
-     * @return
-     */
-    public Map<Long,BigDecimal> getInitialStockMapByMaterialList(List<MaterialVo4Unit> list) {
-        Map<Long,BigDecimal> map = new HashMap<>();
-        List<Long> materialIdList = new ArrayList<>();
-        for(MaterialVo4Unit materialVo4Unit: list) {
-            materialIdList.add(materialVo4Unit.getId());
-        }
-        List<MaterialInitialStock> mcsList = materialInitialStockMapperEx.getInitialStockMapByIdList(materialIdList);
-        for(MaterialInitialStock materialInitialStock: mcsList) {
-            map.put(materialInitialStock.getMaterialId(), materialInitialStock.getNumber());
-        }
-        return map;
-    }
+    Map<Long,BigDecimal> getInitialStockMapByMaterialList(List<MaterialVo4Unit> list);
 
-    /**
-     * 根据商品列表获取当前库存Map
-     * @param list
-     * @return
-     */
-    public Map<Long,BigDecimal> getCurrentStockMapByMaterialList(List<MaterialVo4Unit> list) {
-        Map<Long,BigDecimal> map = new HashMap<>();
-        List<Long> materialIdList = new ArrayList<>();
-        for(MaterialVo4Unit materialVo4Unit: list) {
-            materialIdList.add(materialVo4Unit.getId());
-        }
-        List<MaterialCurrentStock> mcsList = materialCurrentStockMapperEx.getCurrentStockMapByIdList(materialIdList);
-        for(MaterialCurrentStock materialCurrentStock: mcsList) {
-            map.put(materialCurrentStock.getMaterialId(), materialCurrentStock.getCurrentNumber());
-        }
-        return map;
-    }
+    Map<Long,BigDecimal> getCurrentStockMapByMaterialList(List<MaterialVo4Unit> list);
 
-    /**
-     * 根据商品和仓库获取安全库存信息
-     * @param materialId
-     * @param depotId
-     * @return
-     */
-    public MaterialInitialStock getSafeStock(Long materialId, Long depotId) {
-        MaterialInitialStock materialInitialStock = new MaterialInitialStock();
-        MaterialInitialStockExample example = new MaterialInitialStockExample();
-        example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdEqualTo(depotId)
-                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
-        if(list!=null && list.size()>0) {
-            materialInitialStock = list.get(0);
-        }
-        return materialInitialStock;
-    }
+    MaterialInitialStock getSafeStock(Long materialId, Long depotId);
 
-    public List<MaterialVo4Unit> getMaterialByMeId(Long meId) {
-        List<MaterialVo4Unit> result = new ArrayList<MaterialVo4Unit>();
-        try{
-            if(meId!=null) {
-                result= materialMapperEx.getMaterialByMeId(meId);
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    List<MaterialVo4Unit> getMaterialByMeId(Long meId);
 
-    public String getMaxBarCode() {
-        List<String> barCodeOldList = materialMapperEx.getBarCodeList();
-        // 使用 Stream API 处理条码列表
-        OptionalLong maxBarcode = barCodeOldList.stream()
-                .filter(StringUtil::isNumeric)   // 过滤掉非数字条码
-                .mapToLong(Long::parseLong)      // 将字符串转换为 Long 类型
-                .max();                          // 获取最大值
-        // 如果存在最大值,返回它;否则返回 1000L
-        Long maxBarCodeOld = maxBarcode.orElse(1000L);
-        return maxBarCodeOld + "";
-    }
+    String getMaxBarCode();
 
-    public List<String> getMaterialNameList() {
-        return materialMapperEx.getMaterialNameList();
-    }
+    List<String> getMaterialNameList();
 
-    public List<MaterialVo4Unit> getMaterialByBarCode(String barCode) {
-        String [] barCodeArray=barCode.split(",");
-        return materialMapperEx.getMaterialByBarCode(barCodeArray);
-    }
+    List<MaterialVo4Unit> getMaterialByBarCode(String barCode);
 
-    public List<MaterialVo4Unit> getMaterialByBarCodeAndWithOutMId(String barCode, Long mId) {
-        String [] barCodeArray=barCode.split(",");
-        return materialMapperEx.getMaterialByBarCodeAndWithOutMId(barCodeArray, mId);
-    }
+    List<MaterialVo4Unit> getMaterialByBarCodeAndWithOutMId(String barCode, Long mId);
 
-    public List<MaterialInitialStockWithMaterial> getInitialStockWithMaterial(List<Long> depotList) {
-        return materialMapperEx.getInitialStockWithMaterial(depotList);
-    }
+    List<MaterialInitialStockWithMaterial> getInitialStockWithMaterial(List<Long> depotList);
 
-    public List<MaterialVo4Unit> getListWithStock(List<Long> depotList, List<Long> idList, String position, String materialParam,
-                                                  Boolean moveAvgPriceFlag, Integer zeroStock, String column, String order,
-                                                  Integer offset, Integer rows) throws Exception {
-        Map<Long, BigDecimal> initialStockMap = new HashMap<>();
-        List<MaterialInitialStockWithMaterial> initialStockList = getInitialStockWithMaterial(depotList);
-        for (MaterialInitialStockWithMaterial mism: initialStockList) {
-            initialStockMap.put(mism.getMaterialId(), mism.getNumber());
-        }
-        List<MaterialVo4Unit> dataList = materialMapperEx.getListWithStock(depotList, idList, position, materialParam, zeroStock, column, order, offset, rows);
-        for(MaterialVo4Unit item: dataList) {
-            if(moveAvgPriceFlag) {
-                item.setPurchaseDecimal(item.getCurrentUnitPrice());
-                item.setCurrentStockPrice(item.getCurrentStockMovePrice());
-            }
-            item.setUnitName(null!=item.getUnitId()?item.getUnitName() + "[多单位]":item.getUnitName());
-            item.setInitialStock(null!=initialStockMap.get(item.getId())?initialStockMap.get(item.getId()):BigDecimal.ZERO);
-            item.setBigUnitStock(getBigUnitStock(item.getCurrentStock(), item.getUnitId()));
-            if(fileUploadType == 2) {
-                item.setImgSmall("small");
-                item.setImgLarge("large");
-            }
-        }
-        return dataList;
-    }
+    List<MaterialVo4Unit> getListWithStock(List<Long> depotList, List<Long> idList, String position, String materialParam,
+                                           Boolean moveAvgPriceFlag, Integer zeroStock, String column, String order,
+                                           Integer offset, Integer rows) throws Exception;
 
-    public int getListWithStockCount(List<Long> depotList, List<Long> idList, String position, String materialParam, Integer zeroStock) {
-        return materialMapperEx.getListWithStockCount(depotList, idList, position, materialParam, zeroStock);
-    }
+    int getListWithStockCount(List<Long> depotList, List<Long> idList, String position, String materialParam, Integer zeroStock);
 
-    public MaterialVo4Unit getTotalStockAndPrice(List<Long> depotList, List<Long> idList, String position, String materialParam) {
-        return materialMapperEx.getTotalStockAndPrice(depotList, idList, position, materialParam);
-    }
+    MaterialVo4Unit getTotalStockAndPrice(List<Long> depotList, List<Long> idList, String position, String materialParam);
 
-    /**
-     * 将小单位的库存换算为大单位的库存
-     * @param stock
-     * @param unitId
-     * @return
-     * @throws Exception
-     */
-    public String getBigUnitStock(BigDecimal stock, Long unitId) throws Exception {
-        String bigUnitStock = "";
-        if(null!= unitId) {
-            Unit unit = unitService.getUnit(unitId);
-            if(unit.getRatio()!=null && unit.getRatio().compareTo(BigDecimal.ZERO)!=0 && stock!=null) {
-                bigUnitStock = stock.divide(unit.getRatio(),2,BigDecimal.ROUND_HALF_UP) + unit.getOtherUnit();
-            }
-        }
-        return bigUnitStock;
-    }
+    String getBigUnitStock(BigDecimal stock, Long unitId) throws Exception;
 
-    /**
-     * 构造扩展信息
-     * @param mpArr
-     * @param m
-     * @return
-     */
-    public String getMaterialOtherByParam(String[] mpArr, MaterialVo4Unit m) {
-        String materialOther = "";
-        for (int i = 0; i < mpArr.length; i++) {
-            if (mpArr[i].equals("自定义1")) {
-                materialOther = materialOther + ((m.getOtherField1() == null || m.getOtherField1().equals("")) ? "" : "(" + m.getOtherField1() + ")");
-            }
-            if (mpArr[i].equals("自定义2")) {
-                materialOther = materialOther + ((m.getOtherField2() == null || m.getOtherField2().equals("")) ? "" : "(" + m.getOtherField2() + ")");
-            }
-            if (mpArr[i].equals("自定义3")) {
-                materialOther = materialOther + ((m.getOtherField3() == null || m.getOtherField3().equals("")) ? "" : "(" + m.getOtherField3() + ")");
-            }
-        }
-        return materialOther;
-    }
+    String getMaterialOtherByParam(String[] mpArr, MaterialVo4Unit m);
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int batchSetMaterialCurrentStock(String ids) throws Exception {
-        int res = 0;
-        List<Long> idList = StringUtil.strToLongList(ids);
-        List<Depot> depotList = depotService.getAllList();
-        for(Long mId: idList) {
-            for(Depot depot: depotList) {
-                depotItemService.updateCurrentStockFun(mId, depot.getId());
-                res = 1;
-            }
-        }
-        return res;
-    }
+    int batchSetMaterialCurrentStock(String ids) throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int batchSetMaterialCurrentUnitPrice(String ids) throws Exception {
-        int res = 0;
-        List<Long> idList = StringUtil.strToLongList(ids);
-        for(Long mId: idList) {
-            DepotItem depotItem = new DepotItem();
-            depotItem.setMaterialId(mId);
-            depotItemService.updateCurrentUnitPrice(depotItem);
-            res = 1;
-        }
-        return res;
-    }
+    int batchSetMaterialCurrentUnitPrice(String ids) throws Exception;
+
+    int batchUpdate(JSONObject jsonObject);
+
+    MaterialExtend getMaterialExtendBySerialNumber(String serialNumber);
 
-    public int batchUpdate(JSONObject jsonObject) {
-        String ids = jsonObject.getString("ids");
-        String materialStr = jsonObject.getString("material");
-        List<Long> idList = StringUtil.strToLongList(ids);
-        Material material = JSONObject.parseObject(materialStr, Material.class);
-        MaterialExample example = new MaterialExample();
-        example.createCriteria().andIdIn(idList).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        return materialMapper.updateByExampleSelective(material, example);
-    }
+    List<MaterialVo4Unit> getMaterialByBatchNumber(String batchNumber);
 
-    public MaterialExtend getMaterialExtendBySerialNumber(String serialNumber) {
-        return materialMapperEx.getMaterialExtendBySerialNumber(serialNumber);
-    }
+    Material getMaterialById(Long id);
 }

+ 1610 - 0
src/main/java/com/jsh/erp/service/impl/MaterialServiceImpl.java

@@ -0,0 +1,1610 @@
+package com.jsh.erp.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jsh.erp.constants.BusinessConstants;
+import com.jsh.erp.constants.ExceptionConstants;
+import com.jsh.erp.datasource.entities.*;
+import com.jsh.erp.datasource.mappers.*;
+import com.jsh.erp.datasource.vo.MaterialVoSearch;
+import com.jsh.erp.exception.BusinessRunTimeException;
+import com.jsh.erp.exception.JshException;
+import com.jsh.erp.service.*;
+import com.jsh.erp.utils.*;
+import jxl.Sheet;
+import jxl.Workbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.math.BigDecimal;
+import java.util.*;
+
+@Service
+public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> implements MaterialService {
+    private Logger logger = LoggerFactory.getLogger(MaterialServiceImpl.class);
+
+    @Resource
+    private MaterialMapper materialMapper;
+    @Resource
+    private MaterialExtendMapper materialExtendMapper;
+    @Resource
+    private MaterialMapperEx materialMapperEx;
+    @Resource
+    private MaterialCategoryMapperEx materialCategoryMapperEx;
+    @Resource
+    private MaterialExtendMapperEx materialExtendMapperEx;
+    @Resource
+    private LogService logService;
+    @Resource
+    private UserService userService;
+    @Resource
+    private DepotItemMapperEx depotItemMapperEx;
+    @Resource
+    private DepotItemService depotItemService;
+    @Resource
+    private MaterialCategoryService materialCategoryService;
+    @Resource
+    private UnitService unitService;
+    @Resource
+    private MaterialInitialStockMapper materialInitialStockMapper;
+    @Resource
+    private MaterialInitialStockMapperEx materialInitialStockMapperEx;
+    @Resource
+    private MaterialCurrentStockMapper materialCurrentStockMapper;
+    @Resource
+    private MaterialCurrentStockMapperEx materialCurrentStockMapperEx;
+    @Resource
+    private DepotService depotService;
+    @Resource
+    private MaterialExtendService materialExtendService;
+    @Resource
+    private SystemConfigService systemConfigService;
+
+    @Value(value="${file.uploadType}")
+    private Long fileUploadType;
+
+    @Override
+    public Material getMaterial(long id)throws Exception {
+        Material result=null;
+        try{
+            result=materialMapper.selectByPrimaryKey(id);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public List<Material> getMaterialListByIds(String ids)throws Exception {
+        List<Long> idList = StringUtil.strToLongList(ids);
+        List<Material> list = new ArrayList<>();
+        try{
+            MaterialExample example = new MaterialExample();
+            example.createCriteria().andIdIn(idList);
+            list = materialMapper.selectByExample(example);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public List<Material> getMaterial() throws Exception{
+        MaterialExample example = new MaterialExample();
+        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        List<Material> list=null;
+        try{
+            list=materialMapper.selectByExample(example);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+
+    /**
+     * 查询商品管理-商品信息列表查询
+     */
+    @Override
+    public List<MaterialVo4Unit> select(String materialParam, String standard, String model, String color, String brand, String mfrs,
+                                        String materialOther, String weight, String expiryNum, String enableSerialNumber,
+                                        String enableBatchNumber, String position, String enabled, String remark, String categoryId,
+                                        String mpList)
+            throws Exception{
+        String[] mpArr = new String[]{};
+        if(StringUtil.isNotEmpty(mpList)){
+            mpArr= mpList.split(",");
+        }
+        List<MaterialVo4Unit> list = new ArrayList<>();
+        try{
+            List<Long> idList = new ArrayList<>();
+            if(StringUtil.isNotEmpty(categoryId)){
+                idList = getListByParentId(Long.parseLong(categoryId));
+            }
+            PageUtils.startPage();
+            list= materialMapperEx.selectByConditionMaterial(materialParam, standard, model, color, brand, mfrs, materialOther, weight, expiryNum,
+                    enableSerialNumber, enableBatchNumber, position, enabled, remark, idList, mpList);
+            if (null != list && list.size()>0) {
+                Map<Long,BigDecimal> initialStockMap = getInitialStockMapByMaterialList(list);
+                Map<Long,BigDecimal> currentStockMap = getCurrentStockMapByMaterialList(list);
+                for (MaterialVo4Unit m : list) {
+                    if(fileUploadType == 2) {
+                        m.setImgSmall("small");
+                        m.setImgLarge("large");
+                    }
+                    m.setMaterialOther(getMaterialOtherByParam(mpArr, m));
+                    m.setInitialStock(initialStockMap.get(m.getId())!=null? initialStockMap.get(m.getId()): BigDecimal.ZERO);
+                    m.setBigUnitInitialStock(getBigUnitStock(m.getInitialStock(), m.getUnitId()));
+                    m.setStock(currentStockMap.get(m.getId())!=null? currentStockMap.get(m.getId()): BigDecimal.ZERO);
+                    m.setBigUnitStock(getBigUnitStock(m.getStock(), m.getUnitId()));
+                }
+            }
+        } catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    /**
+     * 新增商品信息
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int insertMaterial(JSONObject obj, HttpServletRequest request)throws Exception {
+        //商品主表信息
+        Material m = JSONObject.parseObject(obj.toJSONString(), Material.class);
+        m.setEnabled(true);
+        //获取类型编码
+        Long serial_no = materialCategoryService.getMaterialCategory(m.getCategoryId()).getSerialNo();
+        String sku = serial_no + DateUtils.dateTimeNow();
+        //设置系统sku
+        m.setSystemSku(sku);
+
+        try{
+            //添加商品
+            materialMapperEx.insertSelectiveEx(m);
+            Long mId = m.getId();
+            //添加商品拓展记录
+            materialExtendService.saveDetials(obj, obj.getString("sortList"), mId, "insert");
+            //设置初始库存
+            if(obj.get("stock")!=null) {
+                JSONArray stockArr = obj.getJSONArray("stock");
+                for (int i = 0; i < stockArr.size(); i++) {
+                    JSONObject jsonObj = stockArr.getJSONObject(i);
+                    if(jsonObj.get("id")!=null && jsonObj.get("initStock")!=null) {
+                        String number = jsonObj.getString("initStock");
+                        BigDecimal lowSafeStock = null;
+                        BigDecimal highSafeStock = null;
+                        if(jsonObj.get("lowSafeStock")!=null) {
+                            lowSafeStock = jsonObj.getBigDecimal("lowSafeStock");
+                        }
+                        if(jsonObj.get("highSafeStock")!=null) {
+                            highSafeStock = jsonObj.getBigDecimal("highSafeStock");
+                        }
+                        Long depotId = jsonObj.getLong("id");
+                        if(StringUtil.isNotEmpty(number) && Double.parseDouble(number)>0 || lowSafeStock!=null || highSafeStock!=null) {
+                            //设置初始库
+                            insertInitialStockByMaterialAndDepot(depotId, mId, parseBigDecimalEx(number), lowSafeStock, highSafeStock);
+                            //设置当前库
+                            insertCurrentStockByMaterialAndDepot(depotId, mId, parseBigDecimalEx(number));
+                        }
+                    }
+                }
+            }
+            logService.insertLog("商品",
+                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(m.getName()).toString(), request);
+            return 1;
+        }
+        catch (BusinessRunTimeException ex) {
+            throw new BusinessRunTimeException(ex.getCode(), ex.getMessage());
+        }
+        catch(Exception e){
+            JshException.writeFail(logger, e);
+            return 0;
+        }
+    }
+
+    /**
+     * 修改商品
+     * @param obj
+     * @param request
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int updateMaterial(JSONObject obj, HttpServletRequest request) throws Exception{
+        Material material = JSONObject.parseObject(obj.toJSONString(), Material.class);
+        try{
+            //修改商品属性
+            materialMapper.updateByPrimaryKeySelective(material);
+            //
+            if(material.getUnitId() == null) {
+                materialMapperEx.setUnitIdToNull(material.getId());
+            }
+//            if(material.getExpiryNum() == null) {
+//                materialMapperEx.setExpiryNumToNull(material.getId());
+//            }
+            materialExtendService.saveDetials(obj, obj.getString("sortList"),material.getId(), "update");
+            if(obj.get("stock")!=null) {
+                JSONArray stockArr = obj.getJSONArray("stock");
+                for (int i = 0; i < stockArr.size(); i++) {
+                    JSONObject jsonObj = stockArr.getJSONObject(i);
+                    if (jsonObj.get("id") != null && jsonObj.get("initStock") != null) {
+                        String number = jsonObj.getString("initStock");
+                        BigDecimal lowSafeStock = null;
+                        BigDecimal highSafeStock = null;
+                        if(jsonObj.get("lowSafeStock")!=null) {
+                            lowSafeStock = jsonObj.getBigDecimal("lowSafeStock");
+                        }
+                        if(jsonObj.get("highSafeStock")!=null) {
+                            highSafeStock = jsonObj.getBigDecimal("highSafeStock");
+                        }
+                        Long depotId = jsonObj.getLong("id");
+                        //初始库存-先清除再插入
+                        MaterialInitialStockExample example = new MaterialInitialStockExample();
+                        example.createCriteria().andMaterialIdEqualTo(material.getId()).andDepotIdEqualTo(depotId);
+                        materialInitialStockMapper.deleteByExample(example);
+                        if (StringUtil.isNotEmpty(number) || lowSafeStock!=null || highSafeStock!=null) {
+                            insertInitialStockByMaterialAndDepot(depotId, material.getId(), parseBigDecimalEx(number), lowSafeStock, highSafeStock);
+                        }
+                        //更新当前库存
+                        depotItemService.updateCurrentStockFun(material.getId(), depotId);
+                    }
+                }
+            }
+            logService.insertLog("商品",
+                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(material.getName()).toString(), request);
+            return 1;
+        }catch(Exception e){
+            JshException.writeFail(logger, e);
+            return 0;
+        }
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int deleteMaterial(Long id, HttpServletRequest request)throws Exception {
+        return batchDeleteMaterialByIds(id.toString());
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int batchDeleteMaterial(String ids, HttpServletRequest request)throws Exception {
+        return batchDeleteMaterialByIds(ids);
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int batchDeleteMaterialByIds(String ids) throws Exception{
+        String [] idArray=ids.split(",");
+        //校验单据子表	jsh_depot_item
+        List<DepotItem> depotItemList =null;
+        try{
+            depotItemList=  depotItemMapperEx.getDepotItemListListByMaterialIds(idArray);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        if(depotItemList!=null&&depotItemList.size()>0){
+            logger.error("异常码[{}],异常提示[{}],参数,MaterialIds[{}]",
+                    ExceptionConstants.DELETE_FORCE_CONFIRM_CODE,ExceptionConstants.DELETE_FORCE_CONFIRM_MSG,ids);
+            throw new BusinessRunTimeException(ExceptionConstants.DELETE_FORCE_CONFIRM_CODE,
+                    ExceptionConstants.DELETE_FORCE_CONFIRM_MSG);
+        }
+        //记录日志
+        StringBuffer sb = new StringBuffer();
+        sb.append(BusinessConstants.LOG_OPERATION_TYPE_DELETE);
+        //路径列表
+        List<String> pathList = new ArrayList<>();
+        List<Material> list = getMaterialListByIds(ids);
+        for(Material material: list){
+            sb.append("[").append(material.getName()).append("]");
+            if(StringUtil.isNotEmpty(material.getImgName())) {
+                pathList.add(material.getImgName());
+            }
+        }
+        logService.insertLog("商品", sb.toString(),
+                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
+        User userInfo=userService.getCurrentUser();
+        //校验通过执行删除操作
+        try{
+            //逻辑删除商品
+            materialMapperEx.batchDeleteMaterialByIds(new Date(),userInfo==null?null:userInfo.getId(),idArray);
+            //逻辑删除商品价格扩展
+            materialExtendMapperEx.batchDeleteMaterialExtendByMIds(idArray);
+            //逻辑删除文件
+            systemConfigService.deleteFileByPathList(pathList);
+            return 1;
+        }catch(Exception e){
+            JshException.writeFail(logger, e);
+            return 0;
+        }
+    }
+
+    @Override
+    public int checkIsNameExist(Long id, String name)throws Exception {
+        MaterialExample example = new MaterialExample();
+        example.createCriteria().andIdNotEqualTo(id).andNameEqualTo(name).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        List<Material> list =null;
+        try{
+            list=  materialMapper.selectByExample(example);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list==null?0:list.size();
+    }
+
+    @Override
+    public int checkIsExist(Long id, String name, String model, String color, String standard, String mfrs,
+                            String otherField1, String otherField2, String otherField3, String unit, Long unitId)throws Exception {
+        return materialMapperEx.checkIsExist(id, name, model, color, standard, mfrs, otherField1,
+                otherField2, otherField3, unit, unitId);
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int batchSetStatus(Boolean status, String ids)throws Exception {
+        logService.insertLog("商品",
+                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(ids).toString(),
+                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
+        List<Long> materialIds = StringUtil.strToLongList(ids);
+        Material material = new Material();
+        material.setEnabled(status);
+        MaterialExample example = new MaterialExample();
+        example.createCriteria().andIdIn(materialIds);
+        int result =0;
+        try{
+            result=  materialMapper.updateByExampleSelective(material, example);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public Unit findUnit(Long mId)throws Exception{
+        Unit unit = new Unit();
+        try{
+            List<Unit> list = materialMapperEx.findUnitList(mId);
+            if(list!=null && list.size()>0) {
+                unit = list.get(0);
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return unit;
+    }
+
+    @Override
+    public List<MaterialVo4Unit> findById(Long id)throws Exception{
+        List<MaterialVo4Unit> list =null;
+        try{
+            list=  materialMapperEx.findById(id);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public List<MaterialVo4Unit> findByIdWithBarCode(Long meId)throws Exception{
+        List<MaterialVo4Unit> list =null;
+        try{
+            list=  materialMapperEx.findByIdWithBarCode(meId);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    /**
+     * 根据商品类型id获取子类型id集合
+     * @param parentId 商品类型父id
+     * @return
+     */
+    @Override
+    public List<Long> getListByParentId(Long parentId) {
+        List<Long> idList = new ArrayList<Long>();
+        List<MaterialCategory> list = materialCategoryMapperEx.getListByParentId(parentId);
+        idList.add(parentId);
+        if(list!=null && list.size()>0) {
+            getIdListByParentId(idList, parentId);
+        }
+        return idList;
+    }
+
+    @Override
+    public List<Long> getIdListByParentId(List<Long> idList, Long parentId){
+        List<MaterialCategory> list = materialCategoryMapperEx.getListByParentId(parentId);
+        if(list!=null && list.size()>0) {
+            for(MaterialCategory mc : list){
+                idList.add(mc.getId());
+                getIdListByParentId(idList, mc.getId());
+            }
+        }
+        return idList;
+    }
+
+    @Override
+    public JSONArray getMaterialByParam(String materialParam) {
+        JSONArray arr = new JSONArray();
+        List<MaterialVoSearch> list = materialMapperEx.getMaterialByParam(materialParam);
+        for(MaterialVoSearch item: list) {
+            JSONObject obj = new JSONObject();
+            StringBuilder sb = new StringBuilder();
+            sb.append(item.getBatchNumber());
+            sb.append("_").append(item.getName());
+            if(StringUtil.isNotEmpty(item.getMnemonic())) {
+                sb.append("(").append(item.getMnemonic()).append(")");
+            }
+            if(StringUtil.isNotEmpty(item.getStandard())) {
+                sb.append("(").append(item.getStandard()).append(")");
+            }
+            if(StringUtil.isNotEmpty(item.getModel())) {
+                sb.append("(").append(item.getModel()).append(")");
+            }
+            if(StringUtil.isNotEmpty(item.getColor())) {
+                sb.append("(").append(item.getColor()).append(")");
+            }
+            if(StringUtil.isNotEmpty(item.getUnit())) {
+                sb.append("(").append(item.getUnit()).append(")");
+            }
+            obj.put("batchNumber", item.getBatchNumber());
+            obj.put("materialStr", sb.toString());
+            arr.add(obj);
+        }
+        return arr;
+    }
+
+    @Override
+    public List<MaterialVo4Unit> findBySelectWithBarCode(Long categoryId, String q, String standardOrModel, String color,
+                                                         String brand, String mfrs, String enableSerialNumber, String enableBatchNumber,
+                                                         Integer offset, Integer rows, Long depotId) throws Exception{
+        List<MaterialVo4Unit> list =null;
+        try{
+            List<Long> idList = new ArrayList<>();
+            if(categoryId!=null){
+                Long parentId = categoryId;
+                idList = getListByParentId(parentId);
+            }
+            if(StringUtil.isNotEmpty(q)) {
+                q = q.replace("'", "");
+                q = q.trim();
+            }
+            list=  materialMapperEx.findBySelectWithBarCode(idList, q, standardOrModel, color, brand, mfrs,
+                    enableSerialNumber, enableBatchNumber, offset, rows,depotId);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public int findBySelectWithBarCodeCount(Long categoryId, String q, String standardOrModel, String color,
+                                            String brand, String mfrs, String enableSerialNumber, String enableBatchNumber, Long depotId) throws Exception{
+        int result=0;
+        try{
+            List<Long> idList = new ArrayList<>();
+            if(categoryId!=null){
+                Long parentId = categoryId;
+                idList = getListByParentId(parentId);
+            }
+            if(StringUtil.isNotEmpty(q)) {
+                q = q.replace("'", "");
+            }
+            result = materialMapperEx.findBySelectWithBarCodeCount(idList, q, standardOrModel, color, brand, mfrs,
+                    enableSerialNumber, enableBatchNumber,depotId);
+        }catch(Exception e){
+            logger.error("异常码[{}],异常提示[{}],异常[{}]",
+                    ExceptionConstants.DATA_READ_FAIL_CODE,ExceptionConstants.DATA_READ_FAIL_MSG,e);
+            throw new BusinessRunTimeException(ExceptionConstants.DATA_READ_FAIL_CODE,
+                    ExceptionConstants.DATA_READ_FAIL_MSG);
+        }
+        return result;
+    }
+
+    /**
+     * 导出商品信息
+     * @param categoryId
+     * @param materialParam
+     * @param color
+     * @param materialOther
+     * @param weight
+     * @param expiryNum
+     * @param enabled
+     * @param enableSerialNumber
+     * @param enableBatchNumber
+     * @param remark
+     * @param response
+     * @throws Exception
+     */
+    @Override
+    public void exportExcel(String categoryId, String materialParam, String color, String materialOther, String weight,
+                            String expiryNum, String enabled, String enableSerialNumber, String enableBatchNumber,
+                            String remark, HttpServletResponse response)throws Exception {
+        //查询类型子集合id
+        List<Long> idList = new ArrayList<>();
+        if(StringUtil.isNotEmpty(categoryId)){
+            idList = getListByParentId(Long.parseLong(categoryId));
+        }
+        //查询商品主条码相关列表
+        List<MaterialVo4Unit> dataList = materialMapperEx.exportExcel(materialParam, color, materialOther, weight, expiryNum, enabled, enableSerialNumber,
+                enableBatchNumber, remark, idList);
+        //查询商品副条码相关列表
+        Map<Long, MaterialExtend> otherMaterialMap = new HashMap<>();
+        List<MaterialExtend> otherDataList = materialMapperEx.getOtherMaterialList();
+        for(MaterialExtend me: otherDataList) {
+            //遇到多个副条码的情况,只加第一个
+            otherMaterialMap.putIfAbsent(me.getMaterialId(), me);
+        }
+        String nameStr = "名称*,规格,型号,颜色,品牌,类别,基础重量(kg),基本单位*,副单位,基本条码*,副条码,比例,多属性," +
+                "采购价,零售价,销售价,最低售价,状态*,序列号,批号,自定义1,自定义2,自定义3,备注,系统sku,生产日期,保质期,供应商,商品条码,批次号,仓库名称,仓位货架";
+        List<String> nameList = StringUtil.strToStringList(nameStr);
+        //仓库列表
+        List<Depot> depotList = depotService.getAllList();
+        if (nameList != null) {
+            for(Depot depot: depotList) {
+                nameList.add(depot.getName());
+            }
+        }
+        //期初库存缓存
+        List<MaterialInitialStock> misList = materialInitialStockMapperEx.getListExceptZero();
+        Map<String, BigDecimal> misMap = new HashMap<>();
+        if (misList != null) {
+            for (MaterialInitialStock mis : misList) {
+                misMap.put(mis.getMaterialId() + "_" + mis.getDepotId(), mis.getNumber());
+            }
+        }
+        String[] names = StringUtil.listToStringArray(nameList);
+        String title = "商品信息";
+        List<String[]> objects = new ArrayList<>();
+        if (null != dataList) {
+            for (MaterialVo4Unit m : dataList) {
+                String[] objs = new String[names.length];
+                objs[0] = m.getName();
+                objs[1] = m.getStandard();
+                objs[2] = m.getModel();
+                objs[3] = m.getColor();
+                objs[4] = m.getBrand();
+                objs[5] = m.getCategoryName();
+                objs[6] = m.getWeight() == null ? "" : m.getWeight().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
+                objs[7] = m.getCommodityUnit();
+                objs[8] = otherMaterialMap.get(m.getId()) == null ? "" : otherMaterialMap.get(m.getId()).getCommodityUnit();
+                objs[9] = m.getmBarCode();
+                objs[10] = otherMaterialMap.get(m.getId()) == null ? "" : otherMaterialMap.get(m.getId()).getBarCode();
+                objs[11] = m.getRatio() == null ? "" : m.getRatio().toString();
+                objs[12] = m.getSku();
+                objs[13] = m.getPurchaseDecimal() == null ? "" : m.getPurchaseDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
+                objs[14] = m.getCommodityDecimal() == null ? "" : m.getCommodityDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
+                objs[15] = m.getWholesaleDecimal() == null ? "" : m.getWholesaleDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
+                objs[16] = m.getLowDecimal() == null ? "" : m.getLowDecimal().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
+                objs[17] = m.getEnabled() ? "1" : "0";
+                objs[18] = m.getEnableSerialNumber();
+                objs[19] = m.getEnableBatchNumber();
+                objs[20] = m.getOtherField1();
+                objs[21] = m.getOtherField2();
+                objs[22] = m.getOtherField3();
+                objs[23] = m.getRemark();
+                objs[24] = m.getSystemSku();
+                objs[25] = m.getProductionDate() == null ? "" : m.getProductionDate().toString();
+                objs[26] = m.getExpiryNum() == null ? "" : m.getExpiryNum().toString();
+                objs[27] = m.getSupplierId() == null ? "" : m.getSupplierId().toString();
+                objs[28] = m.getBarCode();
+                objs[29] = m.getBatchNumber();
+                objs[30] = m.getDepotId() == null ? "" : m.getDepotId().toString();
+                objs[31] = m.getPosition();
+                //仓库期初库存
+                int i = 32;
+                for(Depot depot: depotList) {
+                    BigDecimal number = misMap.get(m.getId() + "_" + depot.getId());
+                    objs[i] = number == null ? "0" : number.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
+                    i++;
+                }
+                objects.add(objs);
+            }
+        }
+        File file = ExcelUtils.exportObjectsOneSheet(title, "*导入时本行内容请勿删除,切记!", names, title, objects);
+        ExcelUtils.downloadExcel(file, file.getName(), response);
+    }
+
+    /**
+     * 导入商品信息
+     * @param file
+     * @param request
+     * @return
+     * @throws Exception
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public BaseResponseInfo importExcel(MultipartFile file, HttpServletRequest request) throws Exception {
+        BaseResponseInfo info = new BaseResponseInfo();
+        try {
+            Long beginTime = System.currentTimeMillis();
+            //文件扩展名只能为xls
+            String fileName = file.getOriginalFilename();
+            if(StringUtil.isNotEmpty(fileName)) {
+                String fileExt = fileName.substring(fileName.indexOf(".")+1);
+                if(!"xls".equals(fileExt)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXTENSION_ERROR_CODE,
+                            ExceptionConstants.MATERIAL_EXTENSION_ERROR_MSG);
+                }
+            }
+            Workbook workbook = Workbook.getWorkbook(file.getInputStream());
+            Sheet src = workbook.getSheet(0);
+            //获取真实的行数,剔除掉空白行
+            int rightRows = ExcelUtils.getRightRows(src);
+            List<Depot> depotList= depotService.getDepot();
+            int depotCount = depotList.size();
+            Map<String, Long> depotMap = parseDepotToMap(depotList);
+            User user = userService.getCurrentUser();
+            List<MaterialWithInitStock> mList = new ArrayList<>();
+            //单次导入超出1000条
+            if(rightRows > 1002) {
+                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_IMPORT_OVER_LIMIT_CODE,
+                        String.format(ExceptionConstants.MATERIAL_IMPORT_OVER_LIMIT_MSG));
+            }
+            for (int i = 2; i < rightRows; i++) {
+                String name = ExcelUtils.getContent(src, i, 0); //名称
+                String standard = ExcelUtils.getContent(src, i, 1); //规格
+                String model = ExcelUtils.getContent(src, i, 2); //型号
+                String color = ExcelUtils.getContent(src, i, 3); //颜色
+                String brand = ExcelUtils.getContent(src, i, 4); //品牌
+                String categoryName = ExcelUtils.getContent(src, i, 5); //类别
+                String weight = ExcelUtils.getContent(src, i, 6); //基础重量(kg)
+                String expiryNum = ExcelUtils.getContent(src, i, 7); //保质期(天)
+                String unit = ExcelUtils.getContent(src, i, 8); //基本单位
+                //名称为空
+                if(StringUtil.isEmpty(name)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_EMPTY_CODE,
+                            String.format(ExceptionConstants.MATERIAL_NAME_EMPTY_MSG, i+1));
+                }
+                //名称长度超出
+                if(name.length()>100) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_OVER_CODE,
+                            String.format(ExceptionConstants.MATERIAL_NAME_OVER_MSG, i+1));
+                }
+                //规格长度超出
+                if(StringUtil.isNotEmpty(standard) && standard.length()>100) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STANDARD_OVER_CODE,
+                            String.format(ExceptionConstants.MATERIAL_STANDARD_OVER_MSG, i+1));
+                }
+                //型号长度超出
+                if(StringUtil.isNotEmpty(model) && model.length()>100) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_MODEL_OVER_CODE,
+                            String.format(ExceptionConstants.MATERIAL_MODEL_OVER_MSG, i+1));
+                }
+                //基本单位为空
+                if(StringUtil.isEmpty(unit)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_UNIT_EMPTY_CODE,
+                            String.format(ExceptionConstants.MATERIAL_UNIT_EMPTY_MSG, i+1));
+                }
+                //列别为空
+                if(StringUtil.isEmpty(categoryName)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_Category_Name_EMPTY_CODE,
+                            String.format(ExceptionConstants.MATERIAL_Category_Name_EMPTY_MSG, i+1));
+                }
+                MaterialWithInitStock m = new MaterialWithInitStock();
+                m.setName(name);
+                m.setStandard(standard);
+                m.setModel(model);
+                m.setColor(color);
+                m.setBrand(brand);
+                //通过名称生成助记码
+                m.setMnemonic(PinYinUtil.getFirstLettersLo(name));
+                Long categoryId = materialCategoryService.getCategoryIdByName(categoryName);
+                //获取类型编码
+                Long serial_no = categoryId == null ? null : materialCategoryService.getMaterialCategory(m.getCategoryId()).getSerialNo();
+                //设置系统sku
+                m.setSystemSku(serial_no + DateUtils.dateTimeNow());
+                if(null!=categoryId){
+                    m.setCategoryId(categoryId);
+                }
+                if(StringUtil.isNotEmpty(weight)) {
+                    //校验基础重量是否是数字(含小数)
+                    if(!StringUtil.isPositiveBigDecimal(weight)) {
+                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_WEIGHT_NOT_DECIMAL_CODE,
+                                String.format(ExceptionConstants.MATERIAL_WEIGHT_NOT_DECIMAL_MSG, i+1));
+                    }
+                    m.setWeight(new BigDecimal(weight));
+                }
+                if(StringUtil.isNotEmpty(expiryNum)) {
+                    //校验保质期是否是正整数
+                    if(!StringUtil.isPositiveLong(expiryNum)) {
+                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXPIRY_NUM_NOT_INTEGER_CODE,
+                                String.format(ExceptionConstants.MATERIAL_EXPIRY_NUM_NOT_INTEGER_MSG, i+1));
+                    }
+                    //m.setExpiryNum(Integer.parseInt(expiryNum));
+                }
+                String manyUnit = ExcelUtils.getContent(src, i, 9); //副单位
+                String barCode = ExcelUtils.getContent(src, i, 10); //基础条码
+                String manyBarCode = ExcelUtils.getContent(src, i, 11); //副条码
+                String ratio = ExcelUtils.getContent(src, i, 12); //比例
+                String sku = ExcelUtils.getContent(src, i, 13); //多属性
+                String purchaseDecimal = ExcelUtils.getContent(src, i, 14); //采购价
+                String commodityDecimal = ExcelUtils.getContent(src, i, 15); //零售价
+                String wholesaleDecimal = ExcelUtils.getContent(src, i, 16); //销售价
+                String lowDecimal = ExcelUtils.getContent(src, i, 17); //最低售价
+                String enabled = ExcelUtils.getContent(src, i, 18); //状态
+                String enableSerialNumber = ExcelUtils.getContent(src, i, 19); //序列号
+                String enableBatchNumber = ExcelUtils.getContent(src, i, 20); //批号
+                String position = ExcelUtils.getContent(src, i, 21); //仓位货架
+                String mfrs = ExcelUtils.getContent(src, i, 22); //制造商
+                String otherField1 = ExcelUtils.getContent(src, i, 23); //自定义1
+                String otherField2 = ExcelUtils.getContent(src, i, 24); //自定义2
+                String otherField3 = ExcelUtils.getContent(src, i, 25); //自定义3
+                String remark = ExcelUtils.getContent(src, i, 26); //备注
+               // m.setPosition(StringUtil.isNotEmpty(position)?position:null);
+                //m.setMfrs(StringUtil.isNotEmpty(mfrs)?mfrs:null);
+                m.setOtherField1(StringUtil.isNotEmpty(otherField1)?otherField1:null);
+                m.setOtherField2(StringUtil.isNotEmpty(otherField2)?otherField2:null);
+                m.setOtherField3(StringUtil.isNotEmpty(otherField3)?otherField3:null);
+                m.setRemark(remark);
+                //状态格式错误
+                if(!"1".equals(enabled) && !"0".equals(enabled)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ENABLED_ERROR_CODE,
+                            String.format(ExceptionConstants.MATERIAL_ENABLED_ERROR_MSG, i+1));
+                }
+                //基本条码为空
+                if(StringUtil.isEmpty(barCode)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_EMPTY_CODE,
+                            String.format(ExceptionConstants.MATERIAL_BARCODE_EMPTY_MSG, i+1));
+                }
+                //校验基本条码长度为4到40位
+                if(!StringUtil.checkBarCodeLength(barCode)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_CODE,
+                            String.format(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_MSG, barCode));
+                }
+                //校验副条码长度为4到40位
+                if(StringUtil.isNotEmpty(manyBarCode) && !StringUtil.checkBarCodeLength(manyBarCode)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_CODE,
+                            String.format(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_MSG, manyBarCode));
+                }
+                //批量校验excel中有无重复商品,是指名称、规格、型号、颜色、单位、多属性
+                batchCheckExistMaterialListByParam(mList, name, standard, model, color, unit, sku);
+                //批量校验excel中有无重复条码(1-文档自身校验,2-和数据库里面的商品校验)
+                batchCheckExistBarCodeByParam(mList, barCode, manyBarCode);
+                //设置商品拓展属性
+                JSONObject materialExObj = new JSONObject();
+                JSONObject basicObj = new JSONObject();
+                basicObj.put("barCode", barCode);
+                basicObj.put("commodityUnit", unit);
+                basicObj.put("sku", sku);
+                basicObj.put("purchaseDecimal", purchaseDecimal);
+                basicObj.put("commodityDecimal", commodityDecimal);
+                basicObj.put("wholesaleDecimal", wholesaleDecimal);
+                basicObj.put("lowDecimal", lowDecimal);
+                materialExObj.put("basic", basicObj);
+                if(StringUtil.isNotEmpty(manyUnit) && StringUtil.isNotEmpty(ratio)){ //多单位
+                    //校验比例是否是数字(含小数)
+                    if(!StringUtil.isPositiveBigDecimal(ratio.trim())) {
+                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_RATIO_NOT_INTEGER_CODE,
+                                String.format(ExceptionConstants.MATERIAL_RATIO_NOT_INTEGER_MSG, i+1));
+                    }
+                    Long unitId = unitService.getUnitIdByParam(unit, manyUnit, new BigDecimal(ratio.trim()));
+                    if(unitId != null) {
+                        m.setUnitId(unitId);
+                        m.setUnit("");
+                    } else {
+                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_UNIT_MATE_CODE,
+                                String.format(ExceptionConstants.MATERIAL_UNIT_MATE_MSG, manyBarCode));
+                    }
+                    JSONObject otherObj = new JSONObject();
+                    otherObj.put("barCode", manyBarCode);
+                    otherObj.put("commodityUnit", manyUnit);
+                    otherObj.put("purchaseDecimal", parsePrice(purchaseDecimal,ratio));
+                    otherObj.put("commodityDecimal", parsePrice(commodityDecimal,ratio));
+                    otherObj.put("wholesaleDecimal", parsePrice(wholesaleDecimal,ratio));
+                    otherObj.put("lowDecimal", parsePrice(lowDecimal,ratio));
+                    materialExObj.put("other", otherObj);
+                } else {
+                    m.setUnit(unit);
+                    m.setUnitId(null);
+                }
+                m.setMaterialExObj(materialExObj);
+                m.setEnabled("1".equals(enabled));
+                if(StringUtil.isNotEmpty(enableSerialNumber) && "1".equals(enableSerialNumber)) {
+                    m.setEnableSerialNumber("1");
+                } else {
+                    m.setEnableSerialNumber("0");
+                }
+                if(StringUtil.isNotEmpty(enableBatchNumber) && "1".equals(enableBatchNumber)) {
+                    m.setEnableBatchNumber("1");
+                } else {
+                    m.setEnableBatchNumber("0");
+                }
+                if("1".equals(enableSerialNumber) && "1".equals(enableBatchNumber)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ENABLE_MUST_ONE_CODE,
+                            String.format(ExceptionConstants.MATERIAL_ENABLE_MUST_ONE_MSG, barCode));
+                }
+                m.setStockMap(getStockMapCache(src, depotCount, depotMap, i));
+                mList.add(m);
+            }
+            List<Long> deleteInitialStockMaterialIdList = new ArrayList<>();
+            List<Long> deleteCurrentStockMaterialIdList = new ArrayList<>();
+            List<MaterialInitialStock> insertInitialStockMaterialList = new ArrayList<>();
+            List<MaterialCurrentStock> insertCurrentStockMaterialList = new ArrayList<>();
+            //防止初始库存和当前库存出现重复
+            Map<String, String> materialDepotInitialMap = new HashMap<>();
+            Map<String, String> materialDepotCurrentMap = new HashMap<>();
+            for(MaterialWithInitStock m: mList) {
+                Long mId = 0L;
+                //判断该商品是否存在,如果不存在就新增,如果存在就更新
+                String basicBarCode = getBasicBarCode(m);
+                //根据条件返回产品列表
+                List<Material> materials = getMaterialListByParam(m.getName(),m.getStandard(),m.getModel(),m.getColor(),m.getUnit(),m.getUnitId(), basicBarCode);
+                if(materials.size() == 0) { //产品列表为0,新增商品
+                    materialMapperEx.insertSelectiveEx(m);
+                    mId = m.getId();
+                } else { //产品列表不为0,商品存在,修改商品属性
+                    mId = materials.get(0).getId();
+                    String materialJson = JSON.toJSONString(m);
+                    Material material = JSONObject.parseObject(materialJson, Material.class);
+                    material.setId(mId);
+                    materialMapper.updateByPrimaryKeySelective(material);
+                    //更新多单位
+                    if(material.getUnitId() == null) {
+                        materialMapperEx.setUnitIdToNull(material.getId());
+                    }
+                    //如果之前有保质期,则更新保质期
+//                    if(materials.get(0).getExpiryNum()!=null && material.getExpiryNum() == null) {
+//                        materialMapperEx.setExpiryNumToNull(material.getId());
+//                    }
+                }
+                //给商品新增或更新条码与价格相关信息
+                JSONObject materialExObj = m.getMaterialExObj();
+                insertOrUpdateMaterialExtend(materialExObj, "basic", "1", mId, user);
+                insertOrUpdateMaterialExtend(materialExObj, "other", "0", mId, user);
+                //给商品更新库存
+                Map<Long, BigDecimal> stockMap = m.getStockMap();
+                for(Depot depot: depotList){
+                    Long depotId = depot.getId();
+                    String materialDepotKey = mId + "_" + depotId;
+                    //获取初始库存
+                    BigDecimal initStock = getInitStock(mId, depotId);
+                    //excel里面的当前库存
+                    BigDecimal stock = stockMap.get(depot.getId());
+                    //新增或更新初始库存
+                    if(stock!=null && stock.compareTo(BigDecimal.ZERO)!=0) {
+                        String basicStr = materialExObj.getString("basic");
+                        MaterialExtend materialExtend = JSONObject.parseObject(basicStr, MaterialExtend.class);
+                        if(StringUtil.isNotEmpty(materialExtend.getSku())) {
+                            throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_SKU_BEGIN_STOCK_FAILED_CODE,
+                                    String.format(ExceptionConstants.MATERIAL_SKU_BEGIN_STOCK_FAILED_MSG, materialExtend.getBarCode()));
+                        }
+                        buildChangeInitialStock(deleteInitialStockMaterialIdList, insertInitialStockMaterialList, materialDepotInitialMap, mId, depotId, materialDepotKey, stock);
+                    } else {
+                        if(initStock.compareTo(BigDecimal.ZERO)!=0) {
+                            buildChangeInitialStock(deleteInitialStockMaterialIdList, insertInitialStockMaterialList, materialDepotInitialMap, mId, depotId, materialDepotKey, stock);
+                        }
+                    }
+                    //新增或更新当前库存
+                    Long billCount = depotItemService.getCountByMaterialAndDepot(mId, depotId);
+                    if(billCount == 0) {
+                        if(stock!=null && stock.compareTo(BigDecimal.ZERO)!=0) {
+                            buildChangeCurrentStock(deleteCurrentStockMaterialIdList, insertCurrentStockMaterialList, materialDepotCurrentMap, mId, depotId, materialDepotKey, stock);
+                        } else {
+                            if(initStock.compareTo(BigDecimal.ZERO)!=0) {
+                                buildChangeCurrentStock(deleteCurrentStockMaterialIdList, insertCurrentStockMaterialList, materialDepotCurrentMap, mId, depotId, materialDepotKey, stock);
+                            }
+                        }
+                    } else {
+                        BigDecimal currentNumber = getCurrentStockByMaterialIdAndDepotId(mId, depotId);
+                        //当前库存的更新:减去初始库存,再加上导入的新初始库存
+                        if(currentNumber!=null && initStock!=null && stock!=null) {
+                            currentNumber = currentNumber.subtract(initStock).add(stock);
+                        }
+                        buildChangeCurrentStock(deleteCurrentStockMaterialIdList, insertCurrentStockMaterialList, materialDepotCurrentMap, mId, depotId, materialDepotKey, currentNumber);
+                    }
+                }
+            }
+            //批量更新库存,先删除后新增
+            if(insertInitialStockMaterialList.size()>0) {
+                batchDeleteInitialStockByMaterialList(deleteInitialStockMaterialIdList);
+                materialInitialStockMapperEx.batchInsert(insertInitialStockMaterialList);
+            }
+            if(insertCurrentStockMaterialList.size()>0) {
+                batchDeleteCurrentStockByMaterialList(deleteCurrentStockMaterialIdList);
+                materialCurrentStockMapperEx.batchInsert(insertCurrentStockMaterialList);
+            }
+            //添加日志
+            logService.insertLog("商品",
+                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_IMPORT).append(mList.size()).append(BusinessConstants.LOG_DATA_UNIT).toString(),
+                    ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
+            Long endTime = System.currentTimeMillis();
+            logger.info("导入耗时:{}", endTime-beginTime);
+            info.code = 200;
+            info.data = "导入成功";
+        } catch (BusinessRunTimeException e) {
+            info.code = e.getCode();
+            info.data = e.getData().get("message");
+        } catch (Exception e) {
+            logger.error(e.getMessage(), e);
+            info.code = 500;
+            info.data = "导入失败";
+        }
+        return info;
+    }
+
+    /**
+     * 构造初始库存的变化
+     */
+    private void buildChangeInitialStock(List<Long> deleteInitialStockMaterialIdList, List<MaterialInitialStock> insertInitialStockMaterialList,
+                                         Map<String, String> materialDepotInitialMap, Long mId, Long depotId, String materialDepotKey, BigDecimal stock) {
+        if(materialDepotInitialMap.get(materialDepotKey)==null) {
+            MaterialInitialStock materialInitialStock = new MaterialInitialStock();
+            materialInitialStock.setMaterialId(mId);
+            materialInitialStock.setDepotId(depotId);
+            materialInitialStock.setNumber(stock);
+            insertInitialStockMaterialList.add(materialInitialStock);
+            deleteInitialStockMaterialIdList.add(mId);
+            materialDepotInitialMap.put(materialDepotKey, materialDepotKey);
+        }
+    }
+
+    /**
+     * 构造当前库存的变化
+     */
+    private void buildChangeCurrentStock(List<Long> deleteCurrentStockMaterialIdList, List<MaterialCurrentStock> insertCurrentStockMaterialList,
+                                         Map<String, String> materialDepotCurrentMap, Long mId, Long depotId, String materialDepotKey, BigDecimal stock) {
+        if(materialDepotCurrentMap.get(materialDepotKey)==null) {
+            MaterialCurrentStock materialCurrentStock = new MaterialCurrentStock();
+            materialCurrentStock.setMaterialId(mId);
+            materialCurrentStock.setDepotId(depotId);
+            materialCurrentStock.setCurrentNumber(stock);
+            insertCurrentStockMaterialList.add(materialCurrentStock);
+            deleteCurrentStockMaterialIdList.add(mId);
+            materialDepotCurrentMap.put(materialDepotKey, materialDepotKey);
+        }
+    }
+
+    private Map<String, Long> parseDepotToMap(List<Depot> depotList) {
+        Map<String, Long> map = new HashMap<>();
+        for(Depot depot: depotList) {
+            map.put(depot.getName(), depot.getId());
+        }
+        return map;
+    }
+
+    /**
+     * 缓存各个仓库的库存信息
+     * @param src
+     * @param depotCount
+     * @param depotMap
+     * @param i
+     * @return
+     * @throws Exception
+     */
+    private Map<Long, BigDecimal> getStockMapCache(Sheet src, int depotCount, Map<String, Long> depotMap, int i) throws Exception {
+        Map<Long, BigDecimal> stockMap = new HashMap<>();
+        for(int j = 1; j<= depotCount; j++) {
+            int col = 26 + j;
+            if(col < src.getColumns()){
+                String depotName = ExcelUtils.getContent(src, 1, col); //获取仓库名称
+                if(StringUtil.isNotEmpty(depotName)) {
+                    Long depotId = depotMap.get(depotName);
+                    if(depotId!=null && depotId!=0L){
+                        String stockStr = ExcelUtils.getContent(src, i, col);
+                        if(StringUtil.isNotEmpty(stockStr)) {
+                            stockMap.put(depotId, parseBigDecimalEx(stockStr));
+                        }
+                    }
+                }
+            }
+        }
+        return stockMap;
+    }
+
+    /**
+     * 批量校验excel中有无重复商品,是指名称、规格、型号、颜色、单位
+     * @param mList
+     */
+    @Override
+    public void batchCheckExistMaterialListByParam(List<MaterialWithInitStock> mList, String name, String standard,
+                                                   String model, String color, String unit, String sku) {
+        for(MaterialWithInitStock material: mList){
+            String materialSku = "";
+            JSONObject materialExObj = material.getMaterialExObj();
+            if(materialExObj!=null && materialExObj.get("basic")!=null) {
+                JSONObject basicObj = materialExObj.getJSONObject("basic");
+                if(basicObj!=null && materialExObj.get("sku")!=null) {
+                    materialSku = basicObj.getString("sku");
+                }
+            }
+            if(name.equals(material.getName()) &&
+                    standard.equals(material.getStandard()) &&
+                    model.equals(material.getModel()) &&
+                    color.equals(material.getColor()) &&
+                    unit.equals(material.getUnit()) &&
+                    sku.equals(materialSku)) {
+                String info = name + "-" + standard + "-" + model + "-" + color + "-" + unit + "-" + sku;
+                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_EXIST_CODE,
+                        String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_EXIST_MSG, info));
+            }
+        }
+    }
+
+    /**
+     * 批量校验excel中有无重复条码(1-文档自身校验,2-和数据库里面的商品校验)
+     * @param mList
+     */
+    @Override
+    public void batchCheckExistBarCodeByParam(List<MaterialWithInitStock> mList,
+                                              String barCode, String manyBarCode) throws Exception {
+        if(StringUtil.isNotEmpty(manyBarCode)) {
+            if(barCode.equals(manyBarCode)) {
+                //同一个商品的主副条码重复了,进行提醒
+                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_CODE,
+                        String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_MSG, manyBarCode));
+            }
+            //EXCEL中有副条码在系统中已存在(除自身商品之外)
+            int count = materialExtendService.getCountByManyBarCodeWithoutUs(manyBarCode, barCode);
+            if (count>0) {
+                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_MANY_BARCODE_EXIST_CODE,
+                        String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_MANY_BARCODE_EXIST_MSG, manyBarCode));
+            }
+        }
+        for(MaterialWithInitStock material: mList){
+            JSONObject materialExObj = material.getMaterialExObj();
+            String basicBarCode = "";
+            String otherBarCode = "";
+            if(materialExObj.get("basic")!=null) {
+                JSONObject basicObj = materialExObj.getJSONObject("basic");
+                basicBarCode = basicObj.getString("barCode");
+            }
+            if(materialExObj.get("other")!=null) {
+                JSONObject otherObj = materialExObj.getJSONObject("other");
+                otherBarCode = otherObj.getString("barCode");
+            }
+            if(barCode.equals(basicBarCode) || barCode.equals(otherBarCode)){
+                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_CODE,
+                        String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_MSG, barCode));
+            }
+            if(StringUtil.isNotEmpty(manyBarCode)) {
+                if(manyBarCode.equals(basicBarCode) || manyBarCode.equals(otherBarCode)){
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_CODE,
+                            String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_MSG, manyBarCode));
+                }
+            }
+        }
+    }
+    /**
+     * 给商品新增或更新条码与价格相关信息
+     * @param materialExObj
+     * @param type
+     * @param defaultFlag
+     * @param mId
+     * @param user
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void insertOrUpdateMaterialExtend(JSONObject materialExObj, String type, String defaultFlag, Long mId, User user) throws Exception {
+        if(StringUtil.isExist(materialExObj.get(type))){
+            //获取对应的商品拓展字符
+            String basicStr = materialExObj.getString(type);
+            MaterialExtend materialExtend = JSONObject.parseObject(basicStr, MaterialExtend.class);
+            materialExtend.setMaterialId(mId);
+            materialExtend.setDefaultFlag(defaultFlag);
+            materialExtend.setCreateTime(new Date());
+            materialExtend.setUpdateTime(System.currentTimeMillis());
+            materialExtend.setCreateSerial(user.getLoginName());
+            materialExtend.setUpdateSerial(user.getLoginName());
+            Long meId = 0L;
+            if(StringUtil.isNotEmpty(materialExtend.getSku())){
+                //含sku的商品,特殊逻辑
+                meId = materialExtendService.selectIdByMaterialIdAndBarCode(mId, materialExtend.getBarCode());
+                List<MaterialExtend> meList = materialExtendService.getListByMaterialIdAndDefaultFlagAndBarCode(mId, "1", materialExtend.getBarCode());
+                if(meList.size() == 0) {
+                    materialExtend.setDefaultFlag("1");
+                } else {
+                    materialExtend.setDefaultFlag("0");
+                }
+            } else {
+                meId = materialExtendService.selectIdByMaterialIdAndDefaultFlag(mId, defaultFlag);
+            }
+            if(meId==0L){
+                materialExtendMapper.insertSelective(materialExtend);
+            } else {
+                materialExtend.setId(meId);
+                materialExtendMapper.updateByPrimaryKeySelective(materialExtend);
+                //如果金额为空,此处单独置空
+                materialExtendMapperEx.specialUpdatePrice(materialExtend);
+            }
+        }
+    }
+
+    @Override
+    public String getBasicBarCode(MaterialWithInitStock m) {
+        String barCode = "";
+        JSONObject materialExObj = m.getMaterialExObj();
+        if(StringUtil.isExist(materialExObj.get("basic"))) {
+            String basicStr = materialExObj.getString("basic");
+            MaterialExtend basicMaterialExtend = JSONObject.parseObject(basicStr, MaterialExtend.class);
+            barCode = basicMaterialExtend.getBarCode();
+        }
+        return barCode;
+    }
+
+    /**
+     * 根据条件返回产品列表
+     * @param name
+     * @param standard
+     * @param model
+     * @param color
+     * @param unit
+     * @param unitId
+     * @return
+     */
+    @Override
+    public List<Material> getMaterialListByParam(String name, String standard, String model, String color, String unit, Long unitId, String basicBarCode) throws Exception {
+        List<Material> list = new ArrayList<>();
+        MaterialExample example = new MaterialExample();
+        MaterialExample.Criteria criteria = example.createCriteria();
+        criteria.andNameEqualTo(name);
+        if (StringUtil.isNotEmpty(model)) {
+            criteria.andModelEqualTo(model);
+        }
+        if (StringUtil.isNotEmpty(color)) {
+            criteria.andColorEqualTo(color);
+        }
+        if (StringUtil.isNotEmpty(standard)) {
+            criteria.andStandardEqualTo(standard);
+        }
+        if (StringUtil.isNotEmpty(unit)) {
+            criteria.andUnitEqualTo(unit);
+        }
+        if (unitId !=null) {
+            criteria.andUnitIdEqualTo(unitId);
+        }
+        criteria.andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        list = materialMapper.selectByExample(example);
+        if(list.size()==0) {
+            //如果通过组合条件没有查到该商品,则通过条码再查一次
+            MaterialExtend materialExtend = materialExtendService.getInfoByBarCode(basicBarCode);
+            if(materialExtend != null && materialExtend.getMaterialId()!=null) {
+                Material material = new Material();
+                material.setId(materialExtend.getMaterialId());
+                list.add(material);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * 写入初始库存
+     * @param depotId 仓库id
+     * @param mId   商品id
+     * @param stock 库存数量
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void insertInitialStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock, BigDecimal lowSafeStock, BigDecimal highSafeStock){
+        MaterialInitialStock materialInitialStock = new MaterialInitialStock();
+        materialInitialStock.setDepotId(depotId);
+        materialInitialStock.setMaterialId(mId);
+        stock = stock == null? BigDecimal.ZERO: stock;
+        materialInitialStock.setNumber(stock);
+        if(lowSafeStock!=null) {
+            materialInitialStock.setLowSafeStock(lowSafeStock);
+        }
+        if(highSafeStock!=null) {
+            materialInitialStock.setHighSafeStock(highSafeStock);
+        }
+        materialInitialStockMapper.insertSelective(materialInitialStock); //存入初始库存
+    }
+
+    /**
+     * 写入当前库存
+     * @param depotId 仓库id
+     * @param mId   商品id
+     * @param stock 库存数量
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void insertCurrentStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock){
+        MaterialCurrentStock materialCurrentStock = new MaterialCurrentStock();
+        materialCurrentStock.setDepotId(depotId);
+        materialCurrentStock.setMaterialId(mId);
+        materialCurrentStock.setCurrentNumber(stock);
+        materialCurrentStockMapper.insertSelective(materialCurrentStock); //存入当前库存
+    }
+
+    /**
+     * 批量删除初始库存
+     * @param mIdList
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void batchDeleteInitialStockByMaterialList(List<Long> mIdList){
+        MaterialInitialStockExample example = new MaterialInitialStockExample();
+        example.createCriteria().andMaterialIdIn(mIdList);
+        materialInitialStockMapper.deleteByExample(example);
+    }
+
+    /**
+     * 批量删除当前库存
+     * @param mIdList
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void batchDeleteCurrentStockByMaterialList(List<Long> mIdList){
+        MaterialCurrentStockExample example = new MaterialCurrentStockExample();
+        example.createCriteria().andMaterialIdIn(mIdList);
+        materialCurrentStockMapper.deleteByExample(example);
+    }
+
+    @Override
+    public List<MaterialVo4Unit> getMaterialEnableSerialNumberList(String q, Integer offset, Integer rows)throws Exception {
+        List<MaterialVo4Unit> list =null;
+        try{
+            list=  materialMapperEx.getMaterialEnableSerialNumberList(q, offset, rows);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public Long getMaterialEnableSerialNumberCount(String q)throws Exception {
+        Long count =null;
+        try{
+            count=  materialMapperEx.getMaterialEnableSerialNumberCount(q);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return count;
+    }
+
+    @Override
+    public BigDecimal parseBigDecimalEx(String str) throws Exception{
+        if(!StringUtil.isEmpty(str)) {
+            return  new BigDecimal(str);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public BigDecimal parsePrice(String price, String ratio) throws Exception{
+        if(StringUtil.isEmpty(price) || StringUtil.isEmpty(ratio)) {
+            return BigDecimal.ZERO;
+        } else {
+            BigDecimal pr=new BigDecimal(price);
+            BigDecimal r=new BigDecimal(ratio);
+            return pr.multiply(r);
+        }
+    }
+
+    /**
+     * 根据商品获取初始库存-多仓库
+     * @param depotList
+     * @param materialId
+     * @return
+     */
+    @Override
+    public BigDecimal getInitStockByMidAndDepotList(List<Long> depotList, Long materialId) {
+        BigDecimal stock = BigDecimal.ZERO;
+        MaterialInitialStockExample example = new MaterialInitialStockExample();
+        if(depotList!=null && depotList.size()>0) {
+            example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdIn(depotList)
+                    .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        } else {
+            example.createCriteria().andMaterialIdEqualTo(materialId)
+                    .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        }
+        List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
+        if(list!=null && list.size()>0) {
+            for(MaterialInitialStock ms: list) {
+                if(ms!=null) {
+                    stock = stock.add(ms.getNumber());
+                }
+            }
+        }
+        return stock;
+    }
+
+    /**
+     * 根据商品和仓库获取初始库存
+     * @param materialId
+     * @param depotId
+     * @return
+     */
+    @Override
+    public BigDecimal getInitStock(Long materialId, Long depotId) {
+        BigDecimal stock = BigDecimal.ZERO;
+        MaterialInitialStockExample example = new MaterialInitialStockExample();
+        example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdEqualTo(depotId)
+                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
+        if(list!=null && list.size()>0) {
+            stock = list.get(0).getNumber();
+        }
+        return stock;
+    }
+
+    /**
+     * 根据商品和仓库获取当前库存
+     * @param materialId
+     * @param depotId
+     * @return
+     */
+    @Override
+    public BigDecimal getCurrentStockByMaterialIdAndDepotId(Long materialId, Long depotId) {
+        BigDecimal stock = BigDecimal.ZERO;
+        MaterialCurrentStockExample example = new MaterialCurrentStockExample();
+        example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdEqualTo(depotId)
+                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        List<MaterialCurrentStock> list = materialCurrentStockMapper.selectByExample(example);
+        if(list!=null && list.size()>0) {
+            stock = list.get(0).getCurrentNumber();
+        } else {
+            stock = getInitStock(materialId,depotId);
+        }
+        return stock;
+    }
+
+    /**
+     * 根据商品列表获取初始库存Map
+     * @param list
+     * @return
+     */
+    @Override
+    public Map<Long,BigDecimal> getInitialStockMapByMaterialList(List<MaterialVo4Unit> list) {
+        Map<Long,BigDecimal> map = new HashMap<>();
+        List<Long> materialIdList = new ArrayList<>();
+        for(MaterialVo4Unit materialVo4Unit: list) {
+            materialIdList.add(materialVo4Unit.getId());
+        }
+        List<MaterialInitialStock> mcsList = materialInitialStockMapperEx.getInitialStockMapByIdList(materialIdList);
+        for(MaterialInitialStock materialInitialStock: mcsList) {
+            map.put(materialInitialStock.getMaterialId(), materialInitialStock.getNumber());
+        }
+        return map;
+    }
+
+    /**
+     * 根据商品列表获取当前库存Map
+     * @param list
+     * @return
+     */
+    @Override
+    public Map<Long,BigDecimal> getCurrentStockMapByMaterialList(List<MaterialVo4Unit> list) {
+        Map<Long,BigDecimal> map = new HashMap<>();
+        List<Long> materialIdList = new ArrayList<>();
+        for(MaterialVo4Unit materialVo4Unit: list) {
+            materialIdList.add(materialVo4Unit.getId());
+        }
+        List<MaterialCurrentStock> mcsList = materialCurrentStockMapperEx.getCurrentStockMapByIdList(materialIdList);
+        for(MaterialCurrentStock materialCurrentStock: mcsList) {
+            map.put(materialCurrentStock.getMaterialId(), materialCurrentStock.getCurrentNumber());
+        }
+        return map;
+    }
+
+    /**
+     * 根据商品和仓库获取安全库存信息
+     * @param materialId
+     * @param depotId
+     * @return
+     */
+    @Override
+    public MaterialInitialStock getSafeStock(Long materialId, Long depotId) {
+        MaterialInitialStock materialInitialStock = new MaterialInitialStock();
+        MaterialInitialStockExample example = new MaterialInitialStockExample();
+        example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdEqualTo(depotId)
+                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
+        if(list!=null && list.size()>0) {
+            materialInitialStock = list.get(0);
+        }
+        return materialInitialStock;
+    }
+
+    @Override
+    public List<MaterialVo4Unit> getMaterialByMeId(Long meId) {
+        List<MaterialVo4Unit> result = new ArrayList<MaterialVo4Unit>();
+        try{
+            if(meId!=null) {
+                result= materialMapperEx.getMaterialByMeId(meId);
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public String getMaxBarCode() {
+        List<String> barCodeOldList = materialMapperEx.getBarCodeList();
+        // 使用 Stream API 处理条码列表
+        OptionalLong maxBarcode = barCodeOldList.stream()
+                .filter(StringUtil::isNumeric)   // 过滤掉非数字条码
+                .mapToLong(Long::parseLong)      // 将字符串转换为 Long 类型
+                .max();                          // 获取最大值
+        // 如果存在最大值,返回它;否则返回 1000L
+        Long maxBarCodeOld = maxBarcode.orElse(1000L);
+        return maxBarCodeOld + "";
+    }
+
+    @Override
+    public List<String> getMaterialNameList() {
+        return materialMapperEx.getMaterialNameList();
+    }
+
+    /**
+     * 根据条码查询商品信息
+     * @param barCode 商品条码
+     */
+    @Override
+    public List<MaterialVo4Unit> getMaterialByBarCode(String barCode) {
+        String [] barCodeArray=barCode.split(",");
+        return materialMapperEx.getMaterialByBarCode(barCodeArray);
+    }
+
+    @Override
+    public List<MaterialVo4Unit> getMaterialByBarCodeAndWithOutMId(String barCode, Long mId) {
+        String [] barCodeArray=barCode.split(",");
+        return materialMapperEx.getMaterialByBarCodeAndWithOutMId(barCodeArray, mId);
+    }
+
+    @Override
+    public List<MaterialInitialStockWithMaterial> getInitialStockWithMaterial(List<Long> depotList) {
+        return materialMapperEx.getInitialStockWithMaterial(depotList);
+    }
+
+    @Override
+    public List<MaterialVo4Unit> getListWithStock(List<Long> depotList, List<Long> idList, String position, String materialParam,
+                                                  Boolean moveAvgPriceFlag, Integer zeroStock, String column, String order,
+                                                  Integer offset, Integer rows) throws Exception {
+        Map<Long, BigDecimal> initialStockMap = new HashMap<>();
+        List<MaterialInitialStockWithMaterial> initialStockList = getInitialStockWithMaterial(depotList);
+        for (MaterialInitialStockWithMaterial mism: initialStockList) {
+            initialStockMap.put(mism.getMaterialId(), mism.getNumber());
+        }
+        List<MaterialVo4Unit> dataList = materialMapperEx.getListWithStock(depotList, idList, position, materialParam, zeroStock, column, order, offset, rows);
+        for(MaterialVo4Unit item: dataList) {
+            if(moveAvgPriceFlag) {
+                item.setPurchaseDecimal(item.getCurrentUnitPrice());
+                item.setCurrentStockPrice(item.getCurrentStockMovePrice());
+            }
+            item.setUnitName(null!=item.getUnitId()?item.getUnitName() + "[多单位]":item.getUnitName());
+            item.setInitialStock(null!=initialStockMap.get(item.getId())?initialStockMap.get(item.getId()):BigDecimal.ZERO);
+            item.setBigUnitStock(getBigUnitStock(item.getCurrentStock(), item.getUnitId()));
+            if(fileUploadType == 2) {
+                item.setImgSmall("small");
+                item.setImgLarge("large");
+            }
+        }
+        return dataList;
+    }
+
+    @Override
+    public int getListWithStockCount(List<Long> depotList, List<Long> idList, String position, String materialParam, Integer zeroStock) {
+        return materialMapperEx.getListWithStockCount(depotList, idList, position, materialParam, zeroStock);
+    }
+
+    @Override
+    public MaterialVo4Unit getTotalStockAndPrice(List<Long> depotList, List<Long> idList, String position, String materialParam) {
+        return materialMapperEx.getTotalStockAndPrice(depotList, idList, position, materialParam);
+    }
+
+    /**
+     * 将小单位的库存换算为大单位的库存
+     * @param stock
+     * @param unitId
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public String getBigUnitStock(BigDecimal stock, Long unitId) throws Exception {
+        String bigUnitStock = "";
+        if(null!= unitId) {
+            Unit unit = unitService.getUnit(unitId);
+            if(unit.getRatio()!=null && unit.getRatio().compareTo(BigDecimal.ZERO)!=0 && stock!=null) {
+                bigUnitStock = stock.divide(unit.getRatio(),2,BigDecimal.ROUND_HALF_UP) + unit.getOtherUnit();
+            }
+        }
+        return bigUnitStock;
+    }
+
+    /**
+     * 构造扩展信息
+     * @param mpArr
+     * @param m
+     * @return
+     */
+    @Override
+    public String getMaterialOtherByParam(String[] mpArr, MaterialVo4Unit m) {
+        String materialOther = "";
+        for (int i = 0; i < mpArr.length; i++) {
+            if (mpArr[i].equals("自定义1")) {
+                materialOther = materialOther + ((m.getOtherField1() == null || m.getOtherField1().equals("")) ? "" : "(" + m.getOtherField1() + ")");
+            }
+            if (mpArr[i].equals("自定义2")) {
+                materialOther = materialOther + ((m.getOtherField2() == null || m.getOtherField2().equals("")) ? "" : "(" + m.getOtherField2() + ")");
+            }
+            if (mpArr[i].equals("自定义3")) {
+                materialOther = materialOther + ((m.getOtherField3() == null || m.getOtherField3().equals("")) ? "" : "(" + m.getOtherField3() + ")");
+            }
+        }
+        return materialOther;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int batchSetMaterialCurrentStock(String ids) throws Exception {
+        int res = 0;
+        List<Long> idList = StringUtil.strToLongList(ids);
+        List<Depot> depotList = depotService.getAllList();
+        for(Long mId: idList) {
+            for(Depot depot: depotList) {
+                depotItemService.updateCurrentStockFun(mId, depot.getId());
+                res = 1;
+            }
+        }
+        return res;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int batchSetMaterialCurrentUnitPrice(String ids) throws Exception {
+        int res = 0;
+        List<Long> idList = StringUtil.strToLongList(ids);
+        for(Long mId: idList) {
+            DepotItem depotItem = new DepotItem();
+            depotItem.setMaterialId(mId);
+            depotItemService.updateCurrentUnitPrice(depotItem);
+            res = 1;
+        }
+        return res;
+    }
+
+    @Override
+    public int batchUpdate(JSONObject jsonObject) {
+        String ids = jsonObject.getString("ids");
+        String materialStr = jsonObject.getString("material");
+        List<Long> idList = StringUtil.strToLongList(ids);
+        Material material = JSONObject.parseObject(materialStr, Material.class);
+        MaterialExample example = new MaterialExample();
+        example.createCriteria().andIdIn(idList).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        return materialMapper.updateByExampleSelective(material, example);
+    }
+
+    @Override
+    public MaterialExtend getMaterialExtendBySerialNumber(String serialNumber) {
+        return materialMapperEx.getMaterialExtendBySerialNumber(serialNumber);
+    }
+
+    /**
+     * 根据批次号查询商品信息
+     * @param batchNumber 批次号
+     */
+    @Override
+    public List<MaterialVo4Unit> getMaterialByBatchNumber(String batchNumber) {
+        String [] batchNumberArray=batchNumber.split(",");
+        return materialMapperEx.getMaterialByBatchNumber(batchNumberArray);
+    }
+
+    /**
+     * 根据商品id查询主表及子表信息
+     * @param id 商品id
+     * @return
+     */
+    @Override
+    public Material getMaterialById(Long id){
+        Material material = materialMapper.selectByPrimaryKey(id);
+        List<MaterialExtend> list = materialExtendMapper.selectByMId(id);
+        material.setList(list);
+        return material;
+    }
+
+}

+ 14 - 9
src/main/resources/mapper_xml/DepotItemMapperEx.xml

@@ -13,6 +13,7 @@
         <result column="all_price" jdbcType="DECIMAL" property="allPrice" />
         <result column="material_unit" jdbcType="VARCHAR" property="materialUnit" />
         <result column="depotName" jdbcType="VARCHAR" property="depotName" />
+        <result column="depotName" jdbcType="VARCHAR" property="depotName" />
         <result column="oTime" jdbcType="TIMESTAMP" property="otime" />
     </resultMap>
 
@@ -150,9 +151,9 @@
         and ifnull(delete_flag,'0') !='1'
     </select>
 
-    <select id="findDetailByDepotIdsAndMaterialIdList" parameterType="com.jsh.erp.datasource.entities.DepotItemExample" resultMap="DetailByTypeAndMIdResultMap">
+    <select id="findDetailByDepotIdsAndMaterialIdList" parameterType="com.jsh.erp.datasource.entities.DepotItemExample" resultType="com.jsh.erp.datasource.entities.DepotItemVo4DetailByTypeAndMId">
         select tb.number, tb.bar_code, tb.material_name, tb.type, tb.sub_type, tb.b_num, tb.unit_price,
-        ifnull(tb.b_num*tb.unit_price,0) as all_price, tb.material_unit, tb.depotName, tb.oTime from
+        ifnull(tb.b_num*tb.unit_price,0) as all_price, tb.material_unit materialUnit, tb.depotName, tb.oTime from
         (select dh.number,me.bar_code,m.name material_name,dh.type,dh.sub_type,
         case
             when type='入库' then ifnull(di.basic_number,0)
@@ -205,7 +206,7 @@
         and di.material_id = #{mId}
         and ifnull(dh.delete_flag,'0') !='1'
         union all
-        --单独构造记录:调拨入库
+
         select dh.number,me.bar_code,m.name material_name,dh.type,dh.sub_type,
         ifnull(di.basic_number,0) as b_num, di.unit_price, di.material_unit,
         (select concat(name,'[调入]') from jsh_depot d where d.id=di.another_depot_id and ifnull(d.delete_flag,'0') !='1') as depotName,
@@ -317,29 +318,33 @@
         and ifnull(dh.delete_flag,'0') !='1') tb
     </select>
 
-    <select id="getDetailList" parameterType="com.jsh.erp.datasource.entities.DepotItemExample" resultMap="ResultWithInfoExMap">
-        select di.*,m.name MName,m.model MModel,m.unit MaterialUnit,m.color MColor,m.standard MStandard,m.mfrs MMfrs,m.weight, m.position, m.img_name,
+    <select id="getDetailList" parameterType="com.jsh.erp.datasource.entities.DepotItemExample" resultType="com.jsh.erp.datasource.entities.DepotItemVo4WithInfoEx">
+        select di.*,m.name MName,m.model MModel,m.unit MaterialUnit,m.color MColor,m.unit_id,m.standard MStandard,m.weight, m.img_name,
         m.other_field1 MOtherField1,m.other_field2 MOtherField2,m.other_field3 MOtherField3,m.enable_serial_number, m.enable_batch_number,
-        m.brand, dp1.name DepotName,dp2.name AnotherDepotName, me.bar_code barCode, me.purchase_decimal
+        m.brand, dp1.name DepotName,dp2.name AnotherDepotName, me.purchase_decimal,
+        me.production_date, me.expiry_num, me.supplier_id, me.bar_code, me.batch_number, me.position,s.supplier supplierName
         from jsh_depot_item di
         left join jsh_material m on di.material_id=m.id  and ifnull(m.delete_flag,'0') !='1'
         left join jsh_material_extend me on me.id=di.material_extend_id  and ifnull(me.delete_Flag,'0') !='1'
         left join jsh_depot dp1 on di.depot_id=dp1.id and ifnull(dp1.delete_Flag,'0') !='1'
         left join jsh_depot dp2 on di.another_depot_id=dp2.id and ifnull(dp2.delete_Flag,'0') !='1'
+        left JOIN jsh_supplier s on me.supplier_id = s.id and ifnull(s.delete_Flag,'0') !='1'
         where di.header_id = #{headerId}
         and ifnull(di.delete_flag,'0') !='1'
         order by di.id asc
     </select>
 
     <select id="getBillDetailListByIds" resultType="com.jsh.erp.datasource.entities.DepotItemVo4WithInfoEx">
-        select di.*,m.name MName,m.model MModel,m.unit MaterialUnit,m.color MColor,m.standard MStandard,m.mfrs MMfrs,m.weight, m.position, m.img_name,
+        select di.*,m.name MName,m.model MModel,m.unit MaterialUnit,m.color MColor,m.unit_id,m.standard MStandard,m.weight, m.img_name,
         m.other_field1 MOtherField1,m.other_field2 MOtherField2,m.other_field3 MOtherField3,m.enable_serial_number, m.enable_batch_number,
-        m.brand, dp1.name DepotName,dp2.name AnotherDepotName, me.bar_code barCode, me.purchase_decimal
+        m.brand, dp1.name DepotName,dp2.name AnotherDepotName, me.purchase_decimal,
+        me.production_date, me.expiry_num, me.supplier_id, me.bar_code, me.batch_number, me.position,s.supplier supplierName
         from jsh_depot_item di
         left join jsh_material m on di.material_id=m.id  and ifnull(m.delete_flag,'0') !='1'
         left join jsh_material_extend me on me.id=di.material_extend_id  and ifnull(me.delete_Flag,'0') !='1'
         left join jsh_depot dp1 on di.depot_id=dp1.id and ifnull(dp1.delete_Flag,'0') !='1'
         left join jsh_depot dp2 on di.another_depot_id=dp2.id and ifnull(dp2.delete_Flag,'0') !='1'
+        left JOIN jsh_supplier s on me.supplier_id = s.id and ifnull(s.delete_Flag,'0') !='1'
         where ifnull(di.delete_flag,'0') !='1'
         and di.header_id in
         <foreach collection="idList" item="item" index="index" separator="," open="(" close=")">
@@ -1011,7 +1016,7 @@
         )
     </select>
 
-    <select id="getBatchNumberList" resultMap="batchNumberListMap">
+    <select id="getBatchNumberList" resultType="com.jsh.erp.datasource.vo.DepotItemVoBatchNumberList">
         select id, bar_code, name, standard, model, unit_id,
         commodity_unit, batch_number, expiration_date, sum(basic_number) total_num from
         (select di.batch_number id, me.bar_code, m.name, m.standard, m.model, m.unit_id,

+ 5 - 1
src/main/resources/mapper_xml/MaterialCategoryMapper.xml

@@ -7,7 +7,7 @@
     <result column="category_level" jdbcType="SMALLINT" property="categoryLevel" />
     <result column="parent_id" jdbcType="BIGINT" property="parentId" />
     <result column="sort" jdbcType="VARCHAR" property="sort" />
-    <result column="serial_no" jdbcType="VARCHAR" property="serialNo" />
+    <result column="serial_no" jdbcType="BIGINT" property="serialNo" />
     <result column="remark" jdbcType="VARCHAR" property="remark" />
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
     <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
@@ -303,4 +303,8 @@
       delete_flag = #{deleteFlag,jdbcType=VARCHAR}
     where id = #{id,jdbcType=BIGINT}
   </update>
+
+  <select id="selectMaxSerialNo" resultType="java.lang.Long">
+    select MAX(serial_no) from jsh_material_category
+  </select>
 </mapper>

+ 19 - 2
src/main/resources/mapper_xml/MaterialExtendMapper.xml

@@ -57,6 +57,7 @@
       </foreach>
     </where>
   </sql>
+
   <sql id="Update_By_Example_Where_Clause">
     <where>
       <foreach collection="example.oredCriteria" item="criteria" separator="or">
@@ -86,11 +87,13 @@
       </foreach>
     </where>
   </sql>
+
   <sql id="Base_Column_List">
-    id, material_id, bar_code, commodity_unit, sku, purchase_decimal, commodity_decimal, 
+    id, material_id, commodity_unit, sku, purchase_decimal, commodity_decimal,
     wholesale_decimal, low_decimal, default_flag, create_time, create_serial, update_serial, 
-    update_time, tenant_id, delete_Flag
+    update_time, tenant_id, delete_Flag,production_date,expiry_num,supplier_id,bar_code,batch_number,inventory,depot_id,position
   </sql>
+
   <select id="selectByExample" parameterType="com.jsh.erp.datasource.entities.MaterialExtendExample" resultMap="BaseResultMap">
     select
     <if test="distinct">
@@ -454,4 +457,18 @@
       delete_Flag = #{deleteFlag,jdbcType=VARCHAR}
     where id = #{id,jdbcType=BIGINT}
   </update>
+
+  <select id="selectByMId" resultMap="BaseResultMap">
+    select
+    <include refid="Base_Column_List" />
+    from jsh_material_extend
+    where delete_Flag = 0
+    and material_id = #{id}
+  </select>
+
+  <select id="selectByBatchNumber" parameterType="com.jsh.erp.datasource.entities.MaterialExtendExample" resultType="com.jsh.erp.datasource.entities.MaterialExtend">
+    select
+    <include refid="Base_Column_List" />
+    from jsh_material_extend WHERE batch_number = #{batchNumber}
+  </select>
 </mapper>

+ 1 - 1
src/main/resources/mapper_xml/MaterialMapper.xml

@@ -91,7 +91,7 @@
   <sql id="Base_Column_List">
     id, category_id, name, model, standard, brand, mnemonic, color, unit, remark,
     img_name, unit_id, weight, enabled, other_field1, other_field2, other_field3,
-    enable_serial_number, enable_batch_number, tenant_id, delete_flag
+    enable_serial_number, enable_batch_number, tenant_id, delete_flag, system_sku, moving_pin_reminder_cycle
   </sql>
 
   <select id="selectByExample" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultMap="BaseResultMap">

+ 41 - 4
src/main/resources/mapper_xml/MaterialMapperEx.xml

@@ -32,6 +32,15 @@
         <result column="meId" jdbcType="BIGINT" property="meId" />
         <result column="unit_name" jdbcType="VARCHAR" property="unitName" />
         <result column="sku" jdbcType="VARCHAR" property="sku" />
+        <result column="production_date" jdbcType="DATE" property="productionDate" />
+        <result column="expiry_num" jdbcType="INTEGER" property="expiryNum" />
+        <result column="supplier_id" jdbcType="BIGINT" property="supplierId" />
+        <result column="bar_code" jdbcType="VARCHAR" property="barCode" />
+        <result column="batch_number" jdbcType="VARCHAR" property="batchNumber" />
+        <result column="inventory" jdbcType="BIGINT" property="inventory" />
+        <result column="depot_id" jdbcType="BIGINT" property="depotId" />
+        <result column="position" jdbcType="VARCHAR" property="position" />
+        <result column="depotName" jdbcType="VARCHAR" property="depotName" />
     </resultMap>
 
     <resultMap id="InitialStockWithMaterialMap" type="com.jsh.erp.datasource.entities.MaterialInitialStockWithMaterial">
@@ -285,7 +294,7 @@
     </select>
 
     <select id="getMaterialByParam" resultType="com.jsh.erp.datasource.vo.MaterialVoSearch">
-        select me.bar_code, m.name, m.mnemonic, m.standard, m.model, m.color, me.commodity_unit unit
+        select me.bar_code, m.name, m.mnemonic, m.standard, m.model, m.color, me.commodity_unit unit, me.batch_number
         from jsh_material m
         left join jsh_material_extend me on m.id = me.material_id and ifnull(me.delete_Flag,'0') !='1'
         where m.enabled=1 and me.id is not null
@@ -298,11 +307,15 @@
         limit 0,20
     </select>
 
-    <select id="findBySelectWithBarCode" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultMap="ResultAndUnitMap">
-        select m.*,u.name unit_name,mc.name categoryName,me.bar_code m_bar_code,me.id meId,me.commodity_unit,me.sku from jsh_material m
+    <select id="findBySelectWithBarCode" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultType="com.jsh.erp.datasource.entities.MaterialVo4Unit">
+        select m.*,u.name unit_name,mc.name categoryName,me.bar_code,me.id meId,me.commodity_unit,me.sku,
+        me.production_date,me.expiry_num,me.supplier_id,me.batch_number,me.depot_id,me.position,d.`name` depotName,s.supplier supplierName
+        from jsh_material m
         left join jsh_material_extend me on m.id=me.material_id and ifnull(me.delete_Flag,'0') !='1'
         left join jsh_unit u on m.unit_id=u.id and ifnull(u.delete_Flag,'0') !='1'
         left JOIN jsh_material_category mc on m.category_id = mc.id and ifnull(mc.delete_Flag,'0') !='1'
+        left JOIN jsh_depot d on me.depot_id = d.id and ifnull(d.delete_Flag,'0') !='1'
+        left JOIN jsh_supplier s on me.supplier_id = s.id and ifnull(s.delete_Flag,'0') !='1'
         where m.enabled=1 and me.id is not null
         <if test="q != null and q !=''">
             <bind name="bindKey" value="'%'+q+'%'"/>
@@ -337,6 +350,9 @@
         <if test="enableBatchNumber != null and enableBatchNumber !=''">
             and m.enable_batch_number = #{enableBatchNumber}
         </if>
+        <if test="depotId != null and depotId !=''">
+            and me.depot_id = #{depotId}
+        </if>
         and ifnull(m.delete_flag,'0') !='1'
         ORDER BY m.id desc, me.default_flag desc, me.id asc
         <if test="offset != null and rows != null">
@@ -382,6 +398,9 @@
         <if test="enableBatchNumber != null and enableBatchNumber !=''">
             and m.enable_batch_number = #{enableBatchNumber}
         </if>
+        <if test="depotId != null and depotId !=''">
+            and me.depot_id = #{depotId}
+        </if>
         and ifnull(m.delete_flag,'0') !='1'
     </select>
 
@@ -546,7 +565,7 @@
 
     <select id="getMaterialByBarCode" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultMap="ResultAndUnitMap">
         select m.*,u.name unit_name, me.id meId,me.bar_code m_bar_code, me.commodity_unit, me.purchase_decimal, me.commodity_decimal,
-        me.wholesale_decimal, me.low_decimal, me.sku
+        me.wholesale_decimal, me.low_decimal, me.sku, me.production_date, me.expiry_num, me.supplier_id, me.bar_code, me.batch_number, me.depot_id, me.position
         from jsh_material m
         left join jsh_material_extend me on m.id=me.material_id and ifnull(me.delete_Flag,'0') !='1'
         left join jsh_unit u on m.unit_id=u.id and ifnull(u.delete_Flag,'0') !='1'
@@ -787,4 +806,22 @@
         limit 0,1
     </select>
 
+    <select id="getMaterialByBatchNumber" parameterType="com.jsh.erp.datasource.entities.MaterialExample" resultType="com.jsh.erp.datasource.entities.MaterialVo4Unit">
+        select m.*,u.name unit_name, me.id meId, me.commodity_unit, me.purchase_decimal, me.commodity_decimal,
+        me.wholesale_decimal, me.low_decimal, me.sku,me.production_date, me.expiry_num, me.supplier_id, me.bar_code, me.batch_number, me.depot_id, me.position,d.`name` depotName,s.supplier supplierName
+        from jsh_material m
+        left join jsh_material_extend me on m.id=me.material_id and ifnull(me.delete_Flag,'0') !='1'
+        left join jsh_unit u on m.unit_id=u.id and ifnull(u.delete_Flag,'0') !='1'
+        left JOIN jsh_depot d on me.depot_id = d.id and ifnull(d.delete_Flag,'0') !='1'
+        left JOIN jsh_supplier s on me.supplier_id = s.id and ifnull(s.delete_Flag,'0') !='1'
+        where
+        me.batch_number in (
+        <foreach collection="batchNumberArray" item="batchNumber" separator=",">
+            #{batchNumber}
+        </foreach>
+        )
+        and ifnull(m.delete_flag,'0') !='1'
+        order by m.id desc, me.default_flag desc, me.id asc
+    </select>
+
 </mapper>