Commit 64146d205b0ede74e0d0326b9e5792ec9f48595d

Authored by wangqian
1 parent 11cc1364

批量入库出库

urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/costfee/vo/MaterialInventoryInImport.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.controller.admin.costfee.vo;
  2 +
  3 +import cn.idev.excel.annotation.ExcelProperty;
  4 +import com.fasterxml.jackson.annotation.JsonFormat;
  5 +import jakarta.validation.constraints.NotEmpty;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import jakarta.validation.constraints.Positive;
  8 +import lombok.AllArgsConstructor;
  9 +import lombok.Builder;
  10 +import lombok.Data;
  11 +import lombok.NoArgsConstructor;
  12 +
  13 +import java.math.BigDecimal;
  14 +import java.time.LocalDate;
  15 +
  16 +/**
  17 + * @Classname MaterialInventoryInImport
  18 + * @Description 物料批量入库
  19 + * @Date 2026/1/15 22:22
  20 + * @Created by wangqian
  21 + */
  22 +@Data
  23 +@Builder
  24 +@AllArgsConstructor
  25 +@NoArgsConstructor
  26 +public class MaterialInventoryInImport {
  27 +
  28 +
  29 + @ExcelProperty(index = 1)
  30 + @NotEmpty(message = "物料名称不能为空")
  31 + private String materialName;
  32 +
  33 + @NotEmpty(message = "耗材类型不能为空")
  34 + @ExcelProperty(index = 2)
  35 + private String materialTypeName;
  36 +
  37 + @NotEmpty(message = "类别名称不能为空")
  38 + @ExcelProperty(index = 3)
  39 + private String typeName;
  40 +
  41 +
  42 + @NotEmpty(message = "类别明细不能为空")
  43 + @ExcelProperty(index = 4)
  44 + private String typeDetailName;
  45 +
  46 + @NotEmpty(message = "物料规格不能为空")
  47 + @ExcelProperty(index = 5)
  48 + private String specifications;
  49 +
  50 + @NotEmpty(message = "物料单位不能为空")
  51 + @ExcelProperty(index = 6)
  52 + private String unitName;
  53 +
  54 + @NotNull(message = "单价不能为空")
  55 + @ExcelProperty(index = 7)
  56 + private BigDecimal materialPrice;
  57 +
  58 + @NotNull(message = "入库数量不能为空")
  59 + @ExcelProperty(index = 8)
  60 + @Positive(message = "数量必须为正整数")
  61 + private Long inInventoryNum;
  62 +
  63 + @NotNull(message = "采购日期不能为空")
  64 + @ExcelProperty(index = 9)
  65 + @JsonFormat(pattern = "yyyy-MM-dd")
  66 + private LocalDate buyDate;
  67 +
  68 + @NotEmpty(message = "供应商名称不能为空")
  69 + @ExcelProperty(index = 10)
  70 + private String supplierName;
  71 +
  72 + @NotEmpty(message = "联系人不能为空")
  73 + @ExcelProperty(index = 11)
  74 + private String contactsName;
  75 +
  76 + @NotEmpty(message = "联系电话不能为空")
  77 + @ExcelProperty(index = 12)
  78 + private String contactsPhone;
  79 +
  80 + @NotEmpty(message = "归属公司不能为空")
  81 + @ExcelProperty(index = 13)
  82 + private String belongCompanyName;
  83 +}
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/costfee/vo/MaterialInventoryOutImport.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.controller.admin.costfee.vo;
  2 +
  3 +import cn.idev.excel.annotation.ExcelProperty;
  4 +import com.fasterxml.jackson.annotation.JsonFormat;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.NotEmpty;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import jakarta.validation.constraints.Positive;
  9 +import lombok.AllArgsConstructor;
  10 +import lombok.Builder;
  11 +import lombok.Data;
  12 +import lombok.NoArgsConstructor;
  13 +
  14 +import java.math.BigDecimal;
  15 +import java.time.LocalDate;
  16 +import java.time.LocalDateTime;
  17 +
  18 +/**
  19 + * @Classname MaterialInventoryOutImport
  20 + * @Description 物料批量出库
  21 + * @Date 2026/1/15 22:22
  22 + * @Created by wangqian
  23 + */
  24 +@Data
  25 +@Builder
  26 +@AllArgsConstructor
  27 +@NoArgsConstructor
  28 +public class MaterialInventoryOutImport {
  29 +
  30 +
  31 +
  32 + @ExcelProperty(index = 1)
  33 + @NotEmpty(message = "物料名称不能为空")
  34 + private String materialName;
  35 +
  36 + @NotEmpty(message = "耗材类型不能为空")
  37 + @ExcelProperty(index = 2)
  38 + private String materialTypeName;
  39 +
  40 + @NotEmpty(message = "类别名称不能为空")
  41 + @ExcelProperty(index = 3)
  42 + private String typeName;
  43 +
  44 + @NotEmpty(message = "类别明细不能为空")
  45 + @ExcelProperty(index = 4)
  46 + private String typeDetailName;
  47 +
  48 + @NotEmpty(message = "物料规格不能为空")
  49 + @ExcelProperty(index = 5)
  50 + private String specifications;
  51 +
  52 + @NotEmpty(message = "物料单位不能为空")
  53 + @ExcelProperty(index = 6)
  54 + private String unitName;
  55 +
  56 + @ExcelProperty(index = 7)
  57 + @NotNull(message = "出库数量不能为空")
  58 + @Positive(message = "数量必须为正整数")
  59 + private Long outInventoryNum;
  60 +
  61 + @NotNull(message = "出库日期不能为空")
  62 + @ExcelProperty(index = 8)
  63 + @JsonFormat(pattern = "yyyy-MM-dd")
  64 + private LocalDate outDate;
  65 +
  66 + @NotEmpty(message = "归属公司不能为空")
  67 + @ExcelProperty(index = 9)
  68 + private String belongCompanyName;
  69 +}
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/enums/TemplateEnum.java
... ... @@ -60,6 +60,20 @@ public enum TemplateEnum {
60 60 2,
61 61 RentalMechanicalCostImport.class,
62 62 true // 新增默认值
  63 + ),
  64 + MATERIAL_INVENTORY_IN(
  65 + "materialInventory_in",
  66 + "物料入库模板.xlsx",
  67 + 1,
  68 + MaterialInventoryInImport.class,
  69 + true // 新增默认值
  70 + ),
  71 + MATERIAL_INVENTORY_OUT(
  72 + "materialInventory_out",
  73 + "物料出库模板.xlsx",
  74 + 1,
  75 + MaterialInventoryOutImport.class,
  76 + true // 新增默认值
63 77 );
64 78  
65 79 // 模板编码(前端传递的标识)
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/costfee/CostFeeServiceImpl.java
... ... @@ -5,12 +5,16 @@ import com.fasterxml.jackson.databind.ObjectMapper;
5 5 import com.zteits.urbanops.module.garden.controller.admin.costfee.CostFeeController;
6 6 import com.zteits.urbanops.module.garden.controller.admin.costfee.vo.*;
7 7 import com.zteits.urbanops.module.garden.dal.dataobject.departmentcost.DepartmentCostDO;
  8 +import com.zteits.urbanops.module.garden.dal.dataobject.material.MaterialDO;
  9 +import com.zteits.urbanops.module.garden.dal.dataobject.materialinventoryin.MaterialInventoryInDO;
  10 +import com.zteits.urbanops.module.garden.dal.dataobject.materialinventoryout.MaterialInventoryOutDO;
8 11 import com.zteits.urbanops.module.garden.dal.dataobject.mechanicalcost.MechanicalCostDO;
9 12 import com.zteits.urbanops.module.garden.dal.dataobject.personalcost.PersonalCostDO;
10 13 import com.zteits.urbanops.module.garden.dal.dataobject.rentalmechanicalcost.RentalMechanicalCostDO;
11 14 import com.zteits.urbanops.module.garden.dal.dataobject.wasterecord.WasteRecordDO;
12 15 import com.zteits.urbanops.module.garden.dal.dataobject.waterfee.WaterFeeDO;
13 16 import com.zteits.urbanops.module.garden.dal.mysql.departmentcost.DepartmentCostMapper;
  17 +import com.zteits.urbanops.module.garden.dal.mysql.material.MaterialMapper;
14 18 import com.zteits.urbanops.module.garden.dal.mysql.mechanicalcost.MechanicalCostMapper;
15 19 import com.zteits.urbanops.module.garden.dal.mysql.personalcost.PersonalCostMapper;
16 20 import com.zteits.urbanops.module.garden.dal.mysql.rentalmechanicalcost.RentalMechanicalCostMapper;
... ... @@ -19,6 +23,9 @@ import com.zteits.urbanops.module.garden.dal.mysql.waterfee.WaterFeeMapper;
19 23 import com.zteits.urbanops.module.garden.enums.AssignTasksConstants;
20 24 import com.zteits.urbanops.module.garden.enums.CostFeeConstants;
21 25 import com.zteits.urbanops.module.garden.enums.TemplateEnum;
  26 +import com.zteits.urbanops.module.garden.service.material.MaterialService;
  27 +import com.zteits.urbanops.module.garden.service.materialinventoryin.MaterialInventoryInService;
  28 +import com.zteits.urbanops.module.garden.service.materialinventoryout.MaterialInventoryOutService;
22 29 import com.zteits.urbanops.module.system.api.dept.DeptApi;
23 30 import com.zteits.urbanops.module.system.api.dept.dto.DeptRespDTO;
24 31 import jakarta.annotation.Resource;
... ... @@ -84,6 +91,12 @@ public class CostFeeServiceImpl implements CostFeeService {
84 91 private RentalMechanicalCostMapper rentalMechanicalCostMapper;
85 92 @Autowired
86 93 private WasteRecordMapper wasteRecordMapper;
  94 + @Resource
  95 + private MaterialMapper materialMapper;
  96 + @Resource
  97 + private MaterialInventoryInService materialInventoryInService;
  98 + @Resource
  99 + private MaterialInventoryOutService materialInventoryOutService;
87 100  
88 101  
89 102 @Override
... ... @@ -412,6 +425,73 @@ public class CostFeeServiceImpl implements CostFeeService {
412 425 }
413 426  
414 427 log.info("成功插入 {} 园林废弃物费用数据", dataList.size());
  428 + } else if (MaterialInventoryInImport.class.isAssignableFrom(importClass)) {
  429 + List<MaterialInventoryInImport> feeList = (List<MaterialInventoryInImport>)dataList;
  430 + List<MaterialInventoryInDO> saveFeeList = new ArrayList<>(CollectionUtils.isEmpty(feeList) ? 0 : feeList.size());
  431 + if (!CollectionUtils.isEmpty(feeList)) {
  432 + Map<String, MaterialDO> materialMap = getMaterialAllMap();
  433 + for (MaterialInventoryInImport importObj : feeList) {
  434 + MaterialInventoryInDO inventoryDO = new MaterialInventoryInDO();
  435 + BeanUtils.copyProperties(importObj, inventoryDO);
  436 + //时间
  437 + inventoryDO.setBuyDate(importObj.getBuyDate().atStartOfDay());
  438 + String checkKey = importObj.getMaterialName() + "|" +
  439 + importObj.getMaterialTypeName() + "|" +
  440 + importObj.getTypeName() + "|" +
  441 + importObj.getTypeDetailName() + "|" +
  442 + importObj.getSpecifications() + "|" +
  443 + importObj.getUnitName();
  444 + MaterialDO materialDO = materialMap.get(checkKey);
  445 + if (materialDO != null) {
  446 + inventoryDO.setMaterialId(materialDO.getMaterialId());
  447 + inventoryDO.setMaterialTypeId(materialDO.getMaterialTypeId());
  448 + inventoryDO.setTypeId(materialDO.getTypeId());
  449 + inventoryDO.setTypeDetailId(materialDO.getTypeDetailId());
  450 + inventoryDO.setUnitId(materialDO.getUnitId());
  451 + inventoryDO.setBelongCompanyId(nameToCompanyIdMap.get(inventoryDO.getBelongCompanyName()));
  452 + }
  453 + saveFeeList.add(inventoryDO);
  454 + }
  455 + }
  456 + //入库
  457 + if (!saveFeeList.isEmpty()) {
  458 + materialInventoryInService.batchCreateMaterialInventoryIn(saveFeeList);
  459 + }
  460 + log.info("成功插入 {} 物料入库数据", dataList.size());
  461 + } else if (MaterialInventoryOutImport.class.isAssignableFrom(importClass)) {
  462 +
  463 + List<MaterialInventoryOutImport> feeList = (List<MaterialInventoryOutImport>)dataList;
  464 + List<MaterialInventoryOutDO> saveFeeList = new ArrayList<>(CollectionUtils.isEmpty(feeList) ? 0 : feeList.size());
  465 + if (!CollectionUtils.isEmpty(feeList)) {
  466 + Map<String, MaterialDO> materialMap = getMaterialAllMap();
  467 + for (MaterialInventoryOutImport importObj : feeList) {
  468 + MaterialInventoryOutDO inventoryDO = new MaterialInventoryOutDO();
  469 + BeanUtils.copyProperties(importObj, inventoryDO);
  470 + //时间
  471 + inventoryDO.setOutDate(importObj.getOutDate().atStartOfDay());
  472 + String checkKey = importObj.getMaterialName() + "|" +
  473 + importObj.getMaterialTypeName() + "|" +
  474 + importObj.getTypeName() + "|" +
  475 + importObj.getTypeDetailName() + "|" +
  476 + importObj.getSpecifications() + "|" +
  477 + importObj.getUnitName();
  478 + MaterialDO materialDO = materialMap.get(checkKey);
  479 + if (materialDO != null) {
  480 + inventoryDO.setMaterialId(materialDO.getMaterialId());
  481 + inventoryDO.setMaterialTypeId(materialDO.getMaterialTypeId());
  482 + inventoryDO.setTypeId(materialDO.getTypeId());
  483 + inventoryDO.setTypeDetailId(materialDO.getTypeDetailId());
  484 + inventoryDO.setUnitId(materialDO.getUnitId());
  485 + inventoryDO.setBelongCompanyId(nameToCompanyIdMap.get(inventoryDO.getBelongCompanyName()));
  486 + }
  487 + saveFeeList.add(inventoryDO);
  488 + }
  489 + }
  490 + //出库
  491 + if (!saveFeeList.isEmpty()) {
  492 + materialInventoryOutService.batchCreateMaterialInventoryOut(saveFeeList);
  493 + }
  494 + log.info("成功插入 {} 物料出库数据", dataList.size());
415 495 }
416 496  
417 497 }
... ... @@ -776,9 +856,112 @@ public class CostFeeServiceImpl implements CostFeeService {
776 856 throw exception0(BAD_REQUEST.getCode(), String.format("第%d条数据校验失败:%s", rowNum, ex.getMessage()), ex);
777 857 }
778 858 }
  859 + } else if (MaterialInventoryInImport.class.isAssignableFrom(importClass)) {
  860 + //物料入库
  861 + List<MaterialInventoryInImport> importList = (List<MaterialInventoryInImport>) dataList;
  862 +
  863 + // 2. 遍历,逐个创建
  864 + for (int i = 0; i < importList.size(); i++) {
  865 + int rowNum = i + 1; // 第i条数据 → 第rowNum行(对应Excel导入的行号逻辑)
  866 + MaterialInventoryInImport importBean = importList.get(i);
  867 +
  868 + try {
  869 + // 2.1 执行校验(替换原 ValidationUtils,直接用 Validator 校验,确保抛出 ConstraintViolationException)
  870 + Set<ConstraintViolation<MaterialInventoryInImport>> violations = validator.validate(importBean);
  871 + if (!violations.isEmpty()) {
  872 + for (ConstraintViolation<MaterialInventoryInImport> violation : violations) {
  873 + //errorMsg.append(violation.getMessage()).append(";");
  874 + throw exception0(BAD_REQUEST.getCode() ,String.format(
  875 + "第[{}]条数据:"+violation.getMessage()
  876 + ), rowNum);
  877 + }
  878 + }
  879 +
  880 + Long companyId = nameToCompanyIdMap.get(importBean.getBelongCompanyName());
  881 + //单位校验
  882 + validatecompany(rowNum, importBean.getBelongCompanyName(), companyId, belongCompanyId);
  883 + } catch (ConstraintViolationException ex) {
  884 + // 5. 包装异常,明确行号 + 真实校验错误(
  885 + throw exception0(BAD_REQUEST.getCode(), String.format("第%d条数据校验失败:%s", rowNum, ex.getMessage()), ex);
  886 + }
  887 + }
  888 + // 业务校验,检查物料信息是否正确
  889 + validateMaterialIn(importList);
  890 +
  891 + } else if (MaterialInventoryOutImport.class.isAssignableFrom(importClass)) {
  892 + //物料出库
  893 + List<MaterialInventoryOutImport> importList = (List<MaterialInventoryOutImport>) dataList;
  894 + // 2. 遍历,逐个创建
  895 + for (int i = 0; i < importList.size(); i++) {
  896 + int rowNum = i + 1; // 第i条数据 → 第rowNum行(对应Excel导入的行号逻辑)
  897 + MaterialInventoryOutImport importBean = importList.get(i);
  898 +
  899 + try {
  900 + // 2.1 执行校验(替换原 ValidationUtils,直接用 Validator 校验,确保抛出 ConstraintViolationException)
  901 + Set<ConstraintViolation<MaterialInventoryOutImport>> violations = validator.validate(importBean);
  902 + if (!violations.isEmpty()) {
  903 + for (ConstraintViolation<MaterialInventoryOutImport> violation : violations) {
  904 + //errorMsg.append(violation.getMessage()).append(";");
  905 + throw exception0(BAD_REQUEST.getCode() ,String.format(
  906 + "第[{}]条数据:"+violation.getMessage()
  907 + ), rowNum);
  908 + }
  909 + }
  910 +
  911 + Long companyId = nameToCompanyIdMap.get(importBean.getBelongCompanyName());
  912 + //单位校验
  913 + validatecompany(rowNum, importBean.getBelongCompanyName(), companyId, belongCompanyId);
  914 + } catch (ConstraintViolationException ex) {
  915 + // 5. 包装异常,明确行号 + 真实校验错误(
  916 + throw exception0(BAD_REQUEST.getCode(), String.format("第%d条数据校验失败:%s", rowNum, ex.getMessage()), ex);
  917 + }
  918 + }
  919 + // 业务校验,检查物料信息是否正确
  920 + validateMaterialOut(importList);
  921 + }
  922 + }
  923 +
  924 + private void validateMaterialIn(List<MaterialInventoryInImport> importList) {
  925 + Set<String> materialSet = getMaterialAllSet();
  926 + for (int i = 0; i < importList.size() ; i++) {
  927 + int rowNum = i + 1;
  928 + MaterialInventoryInImport importBean = importList.get(i);
  929 + String checkKey = importBean.getMaterialName() + "|" +
  930 + importBean.getMaterialTypeName() + "|" +
  931 + importBean.getTypeName() + "|" +
  932 + importBean.getTypeDetailName() + "|" +
  933 + importBean.getSpecifications() + "|" +
  934 + importBean.getUnitName();
  935 +
  936 + if (materialSet.contains(checkKey) == false) {
  937 + throw exception0(BAD_REQUEST.getCode(), String.format(
  938 + "第%d条数据:导入的物料信息有误",
  939 + rowNum
  940 + ));
  941 + }
779 942 }
780 943 }
781 944  
  945 + private void validateMaterialOut(List<MaterialInventoryOutImport> importList) {
  946 + Set<String> materialSet = getMaterialAllSet();
  947 + for (int i = 0; i < importList.size() ; i++) {
  948 + int rowNum = i + 1;
  949 + MaterialInventoryOutImport importBean = importList.get(i);
  950 + String checkKey = importBean.getMaterialName() + "|" +
  951 + importBean.getMaterialTypeName() + "|" +
  952 + importBean.getTypeName() + "|" +
  953 + importBean.getTypeDetailName() + "|" +
  954 + importBean.getSpecifications() + "|" +
  955 + importBean.getUnitName();
  956 +
  957 + if (materialSet.contains(checkKey) == false) {
  958 + throw exception0(BAD_REQUEST.getCode(), String.format(
  959 + "第%d条数据:%s信息有误",
  960 + rowNum, checkKey
  961 + ));
  962 + }
  963 + }
  964 + }
782 965 private void validatecompany(int rowNum, String companyName, Long companyId, Long belongCompanyId){
783 966 // 校验数组长度是否一致
784 967 if (companyId == null) {
... ... @@ -998,4 +1181,52 @@ public class CostFeeServiceImpl implements CostFeeService {
998 1181  
999 1182 return list;
1000 1183 }
  1184 +
  1185 + /**
  1186 + * @Author wangqian
  1187 + * @Description 获取物料详情
  1188 + * @Date 2026/1/16 9:22
  1189 + */
  1190 + private Set<String> getMaterialAllSet() {
  1191 + List<MaterialDO> material = materialMapper.selectList();
  1192 + Set<String> materialKeySet = material.stream()
  1193 + // 第一步:将MaterialDO转换为拼接key(处理空值)
  1194 + .map(CostFeeServiceImpl::buildMaterialKey)
  1195 + // 第三步:收集为Set(HashSet,自动去重)
  1196 + .collect(Collectors.toCollection(HashSet::new));
  1197 +
  1198 + return materialKeySet;
  1199 + }
  1200 + private Map<String, MaterialDO> getMaterialAllMap() {
  1201 + List<MaterialDO> material = materialMapper.selectList();
  1202 + Map<String, MaterialDO> materialMap = material.stream()
  1203 + // 转换为Map:key=拼接字符串,value=MaterialDO
  1204 + .collect(Collectors.toMap(
  1205 + // 第一个参数:生成Map的key(调用抽离的拼接方法)
  1206 + CostFeeServiceImpl::buildMaterialKey,
  1207 + // 第二个参数:生成Map的value(直接用当前MaterialDO对象)
  1208 + m -> m,
  1209 + // 第三个参数:重复key的合并规则(避免DuplicateKeyException)
  1210 + // 规则1:保留第一个出现的对象(推荐,避免覆盖)
  1211 + (existingValue, newValue) -> existingValue
  1212 +
  1213 + ));
  1214 + return materialMap;
  1215 + }
  1216 + /**
  1217 + * 抽离key拼接方法(复用性高,与checkKey规则完全一致)
  1218 + * @param materialDO 物料对象
  1219 + * @return 拼接后的key(格式:A|B|C|D|E|F)
  1220 + */
  1221 + private static String buildMaterialKey(MaterialDO materialDO) {
  1222 + // 空值处理:字段为null时用空字符串替代,避免key中出现null
  1223 + String materialName = materialDO.getMaterialName() == null ? "" : materialDO.getMaterialName();
  1224 + String materialTypeName = materialDO.getMaterialTypeName() == null ? "" : materialDO.getMaterialTypeName();
  1225 + String typeName = materialDO.getTypeName() == null ? "" : materialDO.getTypeName();
  1226 + String typeDetailName = materialDO.getTypeDetailName() == null ? "" : materialDO.getTypeDetailName();
  1227 + String specifications = materialDO.getSpecifications() == null ? "" : materialDO.getSpecifications();
  1228 + String unitName = materialDO.getUnitName() == null ? "" : materialDO.getUnitName();
  1229 +
  1230 + return materialName + "|" + materialTypeName + "|" + typeName + "|" + typeDetailName + "|" + specifications + "|" + unitName;
  1231 + }
1001 1232 }
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/materialinventory/MaterialInventoryServiceImpl.java
... ... @@ -107,6 +107,9 @@ public class MaterialInventoryServiceImpl implements MaterialInventoryService {
107 107 LambdaQueryWrapper<MaterialInventoryDO> queryWrapper = Wrappers.lambdaQuery();
108 108 queryWrapper.eq(MaterialInventoryDO::getBelongCompanyId, materialInventory.getBelongCompanyId());
109 109 queryWrapper.eq(MaterialInventoryDO::getMaterialId, materialInventory.getMaterialId());
  110 + queryWrapper.eq(MaterialInventoryDO::getMaterialTypeId, materialInventory.getMaterialTypeId());
  111 + queryWrapper.eq(MaterialInventoryDO::getTypeDetailId, materialInventory.getTypeDetailId());
  112 + queryWrapper.eq(MaterialInventoryDO::getTypeId, materialInventory.getTypeId());
110 113 MaterialInventoryDO object = materialInventoryMapper.selectOne(queryWrapper);
111 114 if(object != null){
112 115 object.setInventoryTotalNum(object.getInventoryTotalNum()+ materialInventory.getCurrentNum());
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/materialinventoryin/MaterialInventoryInService.java
... ... @@ -58,5 +58,13 @@ public interface MaterialInventoryInService {
58 58 * @return 物料入库分页
59 59 */
60 60 PageResult<MaterialInventoryInDO> getMaterialInventoryInPage(MaterialInventoryInPageReqVO pageReqVO);
  61 + /**
  62 + * @Author wangqian
  63 + * @Description 批量入库
  64 + * @Date 2026/1/16 20:25
  65 + * @Param createReqVO
  66 + * @Return void
  67 + */
  68 + void batchCreateMaterialInventoryIn(List<MaterialInventoryInDO> list);
61 69  
62   -}
63 70 \ No newline at end of file
  71 +}
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/materialinventoryin/MaterialInventoryInServiceImpl.java
... ... @@ -8,6 +8,7 @@ import com.zteits.urbanops.module.garden.dal.mysql.material.MaterialMapper;
8 8 import com.zteits.urbanops.module.garden.service.materialinventory.MaterialInventoryService;
9 9 import com.zteits.urbanops.module.system.api.dept.DeptApi;
10 10 import com.zteits.urbanops.module.system.api.dept.dto.DeptRespDTO;
  11 +import org.apache.commons.collections4.CollectionUtils;
11 12 import org.springframework.stereotype.Service;
12 13 import jakarta.annotation.Resource;
13 14 import org.springframework.validation.annotation.Validated;
... ... @@ -187,4 +188,38 @@ public class MaterialInventoryInServiceImpl implements MaterialInventoryInServic
187 188 return materialInventoryInMapper.selectPage(pageReqVO);
188 189 }
189 190  
  191 +
  192 + @Transactional
  193 + @Override
  194 + public void batchCreateMaterialInventoryIn(List<MaterialInventoryInDO> list) {
  195 + if (CollectionUtils.isEmpty(list)) {
  196 + return;
  197 + }
  198 + for (MaterialInventoryInDO in : list) {
  199 + in.setInventoryInNo(System.currentTimeMillis()+ RandomUtil.randomInt(10, 100000)+"");
  200 + in.setDeptId(getLoginUserDeptId());
  201 + materialInventoryInMapper.insert(in);
  202 +
  203 + //更新库存
  204 + MaterialInventoryDO inventory = new MaterialInventoryDO();
  205 + inventory.setMaterialId(in.getMaterialId());
  206 + inventory.setMaterialName(in.getMaterialName());
  207 + inventory.setMaterialTypeId(in.getMaterialTypeId());
  208 + inventory.setMaterialTypeName(in.getMaterialTypeName());
  209 + inventory.setTypeId(in.getTypeId());
  210 + inventory.setTypeName(in.getTypeName());
  211 + inventory.setTypeDetailId(in.getTypeDetailId());
  212 + inventory.setTypeDetailName(in.getTypeDetailName());
  213 + inventory.setSpecifications(in.getSpecifications());
  214 + inventory.setBelongCompanyId(in.getBelongCompanyId());
  215 + inventory.setBelongCompanyName(in.getBelongCompanyName());
  216 + inventory.setUnitId(in.getUnitId());
  217 + inventory.setUnitName(in.getUnitName());
  218 + inventory.setCurrentNum(in.getInInventoryNum());
  219 + inventory.setOutTotalNum(0L);
  220 + inventory.setInventoryTotalNum(in.getInInventoryNum());
  221 + inventory.setDeptId(getLoginUserDeptId());
  222 + materialInventoryService.insertMaterialInventory(inventory);
  223 + }
  224 + }
190 225 }
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/materialinventoryout/MaterialInventoryOutService.java
... ... @@ -59,4 +59,13 @@ public interface MaterialInventoryOutService {
59 59 */
60 60 PageResult<MaterialInventoryOutDO> getMaterialInventoryOutPage(MaterialInventoryOutPageReqVO pageReqVO);
61 61  
62   -}
63 62 \ No newline at end of file
  63 + /**
  64 + * @Author wangqian
  65 + * @Description 批量出库
  66 + * @Date 2026/1/16 21:40
  67 + * @Param list
  68 + * @Return void
  69 + */
  70 + void batchCreateMaterialInventoryOut(List<MaterialInventoryOutDO> list);
  71 +
  72 +}
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/materialinventoryout/MaterialInventoryOutServiceImpl.java
... ... @@ -14,7 +14,9 @@ import com.zteits.urbanops.module.garden.service.materialinventory.MaterialInven
14 14 import com.zteits.urbanops.module.system.api.dept.DeptApi;
15 15 import com.zteits.urbanops.module.system.api.dept.dto.DeptRespDTO;
16 16 import jakarta.annotation.Resource;
  17 +import org.apache.commons.collections4.CollectionUtils;
17 18 import org.springframework.stereotype.Service;
  19 +import org.springframework.transaction.annotation.Transactional;
18 20 import org.springframework.validation.annotation.Validated;
19 21  
20 22 import java.util.List;
... ... @@ -154,4 +156,33 @@ public class MaterialInventoryOutServiceImpl implements MaterialInventoryOutServ
154 156 return materialInventoryOutMapper.selectPage(pageReqVO);
155 157 }
156 158  
  159 +
  160 + @Override
  161 + @Transactional
  162 + public void batchCreateMaterialInventoryOut(List<MaterialInventoryOutDO> list) {
  163 + if (CollectionUtils.isEmpty(list)) {
  164 + return;
  165 + }
  166 + for (MaterialInventoryOutDO out : list) {
  167 + MaterialInventoryDO materialInventory = materialInventoryService.selectMaterialInventoryByMaterialId(out.getMaterialId(), out.getBelongCompanyId());
  168 + if(null == materialInventory){
  169 + throw exception0(BAD_REQUEST.getCode(),out.getMaterialName()+"没有库存");
  170 + }
  171 +
  172 + //当前库存不足,无法出库
  173 + if(materialInventory.getCurrentNum() < out.getOutInventoryNum()){
  174 + throw exception0(BAD_REQUEST.getCode(),"当前库存不足,无法出库");
  175 + }
  176 + DeptRespDTO deptRespDTO = deptApi.getDept(getCompanyId());
  177 + if(null == deptRespDTO){
  178 + throw exception0(BAD_REQUEST.getCode(), "无效参数-登录人所属单位为空");
  179 + }
  180 + out.setInventoryOutNo(System.currentTimeMillis()+ RandomUtil.randomInt(10, 100000)+"");
  181 + materialInventoryOutMapper.insert(out);
  182 +
  183 + //更新库存
  184 + materialInventoryService.updateInVentoryByMaterialId(materialInventory, out.getOutInventoryNum());
  185 + }
  186 +
  187 + }
157 188 }
... ...