Эх сурвалжийг харах

物资导入模板和物资导入

车车 2 сар өмнө
parent
commit
eab216a4a1

+ 5 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/ServiceException.java

@@ -33,6 +33,11 @@ public final class ServiceException extends RuntimeException {
         this.message = errorCode.getMsg();
     }
 
+    public ServiceException(String message)
+    {
+        this.message = message;
+    }
+
     public ServiceException(Integer code, String message) {
         this.code = code;
         this.message = message;

+ 19 - 19
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materials/MaterialsController.java

@@ -1,14 +1,12 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.materials;
 
+import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialBindingVO;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsPageReqVO;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsRespVO;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsSaveReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.*;
 import cn.iocoder.yudao.module.iscs.service.materials.MaterialsService;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import io.swagger.v3.oas.annotations.Operation;
@@ -18,15 +16,18 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.Valid;
+import org.apache.commons.io.FilenameUtils;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.UPDATE;
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
 @Tag(name = "管理后台 - 物资")
@@ -91,10 +92,9 @@ public class MaterialsController {
         ExcelUtils.write(response, "物资.xls", "数据", MaterialsRespVO.class, list);
     }
 
-    /*@Operation(summary = "导入模板-物资")
+    @Operation(summary = "导入模板-物资")
     @PostMapping("/importTemplate")
-    public void importTemplate(HttpServletResponse response) {
-        ExcelUtil util = new ExcelUtil();
+    public void importTemplate(HttpServletResponse response) throws IOException {
         ImportMaterialsVO importMaterialsVO = new ImportMaterialsVO();
         importMaterialsVO.setCabinetName("测试物资柜(测试示例行可删除)");
         importMaterialsVO.setMaterialsName("测试白大褂K380(测试示例行可删除)");
@@ -105,24 +105,24 @@ public class MaterialsController {
         importMaterialsVO.setExpirationDate(new Date());
         ArrayList<ImportMaterialsVO> importMaterialsVOS = new ArrayList<>();
         importMaterialsVOS.add(importMaterialsVO);
-        util.importTempExcelWithDate(response, "物资数据", importMaterialsVOS);
-    }*/
+        ExcelUtils.write(response, "物资数据.xls", "物资数据", ImportMaterialsVO.class, importMaterialsVOS);
+    }
+
 
-    /*@Operation(summary = "导入-物资")
+
+    @Operation(summary = "导入-物资")
     @ApiAccessLog(operateType = IMPORT)
     @PreAuthorize("@ss.hasPermi('iscs:materials:import')")
     @PostMapping("/importMaterials")
-    public CommonResult<Boolean> importMaterials(MultipartFile file, boolean updateSupport) throws Exception {
+    public CommonResult<String> importMaterials(MultipartFile file) throws Exception {
         String filename = file.getOriginalFilename();
         String extension = FilenameUtils.getExtension(filename);
         // 文件不是 .xlsx 或 .xls
         Assert.isFalse(!"xls".equalsIgnoreCase(extension) && !"xlsx".equalsIgnoreCase(extension), "文件不是xls或xlsx,请重新上传!");
-        ExcelUtil<ImportMaterialsVO> util = new ExcelUtil<>(ImportMaterialsVO.class);
-        List<ImportMaterialsVO> itemList = util.importExcel(file.getInputStream());
-        String operName = getUsername();
-        String message = isMaterialsService.importMaterials(itemList, updateSupport, operName);
-        return AjaxResult.success(message);
-    }*/
+        List<ImportMaterialsVO> list = ExcelUtils.read(file, ImportMaterialsVO.class);
+        String message = materialsService.importMaterials(list);
+        return CommonResult.success(message);
+    }
 
     @Operation(summary = "绑定物资-物资柜绑定物资")
     @PreAuthorize("@ss.hasPermission('iscs:materials:binding')")

+ 4 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materials/vo/ImportMaterialsVO.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.materials.vo;
 
+import com.alibaba.excel.annotation.ExcelIgnore;
 import com.alibaba.excel.annotation.ExcelProperty;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -18,6 +19,7 @@ public class ImportMaterialsVO
 {
 
     @Schema(description = "物资柜ID")
+    @ExcelIgnore
     private Long materialsCabinetId;
 
     @Schema(description = "物资柜Name")
@@ -29,6 +31,7 @@ public class ImportMaterialsVO
     private String materialsName;
 
     @Schema(description = "物资类型ID")
+    @ExcelIgnore
     private Long materialsTypeId;
 
     @ExcelProperty(value = "物资类型")
@@ -50,6 +53,7 @@ public class ImportMaterialsVO
     @ExcelProperty(value = "有效期")
     private Date expirationDate;
 
+    @ExcelIgnore
     private String properties;
 
 }

+ 3 - 4
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/materials/MaterialsService.java

@@ -1,10 +1,7 @@
 package cn.iocoder.yudao.module.iscs.service.materials;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialBindingVO;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsPageReqVO;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsRespVO;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsSaveReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.*;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.materials.MaterialsDO;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -68,4 +65,6 @@ public interface MaterialsService extends IService<MaterialsDO> {
 
     List<MaterialsRespVO> getExMaterials(MaterialBindingVO vo);
 
+    String importMaterials(List<ImportMaterialsVO> itemList) throws JsonProcessingException;
+
 }

+ 116 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/materials/MaterialsServiceImpl.java

@@ -2,14 +2,21 @@ package cn.iocoder.yudao.module.iscs.service.materials;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.*;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.exceptionmisplace.ExceptionMisplaceDO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.materials.MaterialsDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialscabinet.MaterialsCabinetDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialsproperty.MaterialsPropertyDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialspropertyvalue.MaterialsPropertyValueDO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.materialstype.MaterialsTypeDO;
 import cn.iocoder.yudao.module.iscs.dal.mysql.materials.MaterialsMapper;
 import cn.iocoder.yudao.module.iscs.service.exceptionmisplace.ExceptionMisplaceService;
+import cn.iocoder.yudao.module.iscs.service.materialscabinet.MaterialsCabinetService;
+import cn.iocoder.yudao.module.iscs.service.materialsproperty.MaterialsPropertyService;
+import cn.iocoder.yudao.module.iscs.service.materialspropertyvalue.MaterialsPropertyValueService;
 import cn.iocoder.yudao.module.iscs.service.materialstype.MaterialsTypeService;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -44,6 +51,14 @@ public class MaterialsServiceImpl extends ServiceImpl<MaterialsMapper, Materials
     private MaterialsTypeService materialsTypeService;
     @Autowired
     private ExceptionMisplaceService exceptionMisplaceService;
+    @Lazy
+    @Autowired
+    private MaterialsCabinetService materialsCabinetService;
+    @Autowired
+    private MaterialsPropertyValueService materialsPropertyValueService;
+    @Autowired
+    private MaterialsPropertyService materialsPropertyService;
+
 
     @Override
     public Long createMaterials(MaterialsSaveReqVO createReqVO) {
@@ -186,4 +201,105 @@ public class MaterialsServiceImpl extends ServiceImpl<MaterialsMapper, Materials
         return materialsPageVOS;
     }
 
+    @Override
+    public String importMaterials(List<ImportMaterialsVO> itemList) throws JsonProcessingException {
+        Assert.notNull(itemList, "导入物资数据不能为空!");
+        int successNum = 0;
+        int failureNum = 0;
+        StringBuilder successMsg = new StringBuilder();
+        StringBuilder failureMsg = new StringBuilder();
+        for (ImportMaterialsVO materials : itemList) {
+            // 0.检测第一行示例数据有没有被删除
+            if ("测试白大褂(测试示例行可删除)".equals(materials.getMaterialsTypeName()) || "测试实验室(测试示例行可删除)".equals(materials.getSupplier())) {
+                continue;
+            }
+            // 1.定义一个boolean,记录当前这条数据有没有问题
+            boolean result = true;
+            // 1.1定义一个物资类型id
+            Long materialsTypeId = null;
+
+            // 2.-----------------检查物资名称不能为空-------------------------------
+            if (StringUtils.isBlank(materials.getMaterialsName())) {
+                result = false;
+                failureMsg.append("<br/>" + failureNum + "、物资名称 :" + materials.getMaterialsName() + " 不能为空");
+            }
+            // 3.-----------------检查物资类型不能为空-------------------------------
+            if (StringUtils.isNotBlank(materials.getMaterialsTypeName())) {
+                // 3.1检查物资类型是否在我们的系统中
+                List<MaterialsTypeDO> materialsTypelist = materialsTypeService.list(Wrappers.<MaterialsTypeDO>lambdaQuery()
+                        .eq(MaterialsTypeDO::getMaterialsTypeName, materials.getMaterialsTypeName()));
+                if (materialsTypelist.isEmpty()) {
+                    result = false;
+                    failureMsg.append("<br/>" + failureNum + "、物资分类 :" + materials.getMaterialsTypeName() + " 系统中无该物资类型");
+                } else {
+                    materialsTypeId = materialsTypelist.get(0).getId();
+                }
+            } else {
+                result = false;
+                failureMsg.append("<br/>" + failureNum + "、物资分类 :" + materials.getMaterialsName() + " 的物资分类不能为空");
+            }
+            // 4.---------------------检查rfid是否填写------------------------------
+            if (StringUtils.isNotBlank(materials.getMaterialsRfid())) {
+                // 4.1检查rfid是否被使用
+                List<MaterialsDO> materialslist = list(Wrappers.<MaterialsDO>lambdaQuery()
+                        .eq(MaterialsDO::getMaterialsRfid, materials.getMaterialsRfid()));
+                if (!materialslist.isEmpty()) {
+                    result = false;
+                    failureMsg.append("<br/>" + failureNum + "、物资RFID :" + materials.getMaterialsRfid() + " 已被使用");
+                }
+            } else {
+                result = false;
+                failureMsg.append("<br/>" + failureNum + "、物资RFID :" + materials.getMaterialsName() + " 的RFID不能为空");
+            }
+            // 5.---------------------检查物资柜信息------------------------------
+            if (StringUtils.isNotBlank(materials.getCabinetName())) {
+                List<MaterialsCabinetDO> cabinets = materialsCabinetService.list(Wrappers.<MaterialsCabinetDO>lambdaQuery()
+                        .eq(MaterialsCabinetDO::getCabinetName, materials.getCabinetName()));
+                if (!cabinets.isEmpty()) {
+                    materials.setMaterialsCabinetId(cabinets.get(0).getId());
+                }
+            }
+            // 6.---------------------检查物资规格------------------------------
+            if (StringUtils.isNotBlank(materials.getValueName())) {
+                List<MaterialsPropertyValueDO> propertyValueList = materialsPropertyValueService.list(Wrappers.<MaterialsPropertyValueDO>lambdaQuery()
+                        .eq(MaterialsPropertyValueDO::getValueName, materials.getValueName()));
+                if (!propertyValueList.isEmpty()) {
+                    MaterialsPropertyDO property = materialsPropertyService.getById(propertyValueList.get(0).getPropertyId());
+                    PropertyVO propertyVO = new PropertyVO();
+                    propertyVO.setPropertyId(String.valueOf(property.getId()));
+                    propertyVO.setPropertyName(property.getPropertyName());
+                    propertyVO.setRecordId(String.valueOf(propertyValueList.get(0).getId()));
+                    propertyVO.setValueName(propertyValueList.get(0).getValueName());
+                    // 使用 ObjectMapper 将对象转换为 JSON 字符串
+                    ObjectMapper objectMapper = new ObjectMapper();
+                    String jsonString = objectMapper.writeValueAsString(propertyVO);
+                    materials.setProperties("[" + jsonString + "]");
+                }
+            }
+
+            // 开始做最后的插入操作
+            if (result) {
+                successNum++;
+                MaterialsDO bean = BeanUtils.toBean(materials, MaterialsDO.class);
+                bean.setMaterialsTypeId(materialsTypeId);
+                createMaterials(BeanUtils.toBean(bean, MaterialsSaveReqVO.class));
+            } else {
+                failureNum++;
+            }
+
+        }
+        // 总结
+        if (failureNum > 0) {
+            failureMsg.insert(0, "导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
+            throw new ServiceException(failureMsg.toString());
+        } else {
+            if (successNum > 0) {
+                successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条");
+            } else {
+                successMsg.insert(0, "导入失败!");
+            }
+        }
+        return successMsg.toString();
+    }
+
 }

+ 9 - 7
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/statistics/StatisticsApiServiceImpl.java

@@ -176,7 +176,7 @@ public class StatisticsApiServiceImpl implements StatisticsApiService {
             // 5.开始解析
             if (!materials.isEmpty()) {
                 for (InventoryVO inventoryVO : inventoryVOS) {
-                    List<MaterialsDO> cabinetMaterials = materials.stream().filter(o -> o.getMaterialsCabinetId().equals(inventoryVO.getCabinetId())).collect(Collectors.toList());
+                    List<MaterialsDO> cabinetMaterials = materials.stream().filter(o -> o.getMaterialsCabinetId().equals(inventoryVO.getCabinetId())).toList();
                     if (!cabinetMaterials.isEmpty()) {
                         for (MaterialsTypeVO isMaterialsType : inventoryVO.getMaterialsTypeVOList()) {
                             int number = (int) cabinetMaterials.stream().filter(o -> o.getMaterialsTypeId().equals(isMaterialsType.getMaterialsTypeId())).count();
@@ -269,7 +269,7 @@ public class StatisticsApiServiceImpl implements StatisticsApiService {
         List<MaterialsTypeVO> materialsTypeVOList = data.get(0).getMaterialsTypeVOList();
         if (!materialsTypeVOList.isEmpty()) {
             // 每一个typeNames代表一行数据
-            List<String> typeNames = materialsTypeVOList.stream().map(MaterialsTypeVO::getMaterialsTypeName).collect(Collectors.toList());
+            List<String> typeNames = materialsTypeVOList.stream().map(MaterialsTypeVO::getMaterialsTypeName).toList();
             // 开始组装接下来的每一行数据
             for (String typeName : typeNames) {
                 // 构造其他行
@@ -277,7 +277,7 @@ public class StatisticsApiServiceImpl implements StatisticsApiService {
                 strings1.add(typeName);
                 for (InventoryVO datum : data) {
                     // 只会有一条
-                    List<MaterialsTypeVO> collect = datum.getMaterialsTypeVOList().stream().filter(o -> o.getMaterialsTypeName().equals(typeName)).collect(Collectors.toList());
+                    List<MaterialsTypeVO> collect = datum.getMaterialsTypeVOList().stream().filter(o -> o.getMaterialsTypeName().equals(typeName)).toList();
                     strings1.add((collect.get(0).getNumber() == null || collect.get(0).getNumber() == 0) ? "" : String.valueOf(collect.get(0).getNumber()));
                 }
                 lists.add(strings1);
@@ -288,7 +288,7 @@ public class StatisticsApiServiceImpl implements StatisticsApiService {
             sheet.setColumnWidth(i, 5000);
             SXSSFRow row = sheet.createRow(i);
             for (int j = 0; j < lists.get(i).size(); j++) {
-                row.createCell(j).setCellValue(lists.get(i).get(j));
+                row.createCell(j).setCellValue(lists.get(i).get(j) != null ? lists.get(i).get(j) : "0");
             }
         }
     }
@@ -298,10 +298,11 @@ public class StatisticsApiServiceImpl implements StatisticsApiService {
         try {
             output = response.getOutputStream();
             String agent = request.getHeader("USER-AGENT").toLowerCase();
-            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 使用正确的 MIME 类型
+            /*response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 使用正确的 MIME 类型
             response.setContentType("application/force-download");
-            response.setContentType("application/vnd.ms-excel");
-            String codedFileName = URLEncoder.encode(fileName, "UTF-8");
+            response.setContentType("application/vnd.ms-excel");*/
+            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
+            String codedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
             if (agent.contains("firefox")) {
                 response.setCharacterEncoding("utf-8");
                 response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes(), StandardCharsets.UTF_8) + ".xlsx");
@@ -322,6 +323,7 @@ public class StatisticsApiServiceImpl implements StatisticsApiService {
         }
     }
 
+
     @Override
     public void exportBaseData(HttpServletResponse response, HttpServletRequest request, String startTime, String endTime) {
         String fileName = "导出数据";

+ 2 - 2
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/homepage/PageUiComponentController.java

@@ -67,9 +67,9 @@ public class PageUiComponentController {
     @GetMapping("/getPageUiComponentPage")
     @Operation(summary = "获得iscs驾驶舱页面和组件关联分页")
     @PreAuthorize("@ss.hasPermission('sys:page-ui-component:query')")
-    public CommonResult<PageResult<PageUiComponentRespVO>> getPageUiComponentPage(@Valid PageUiComponentPageReqVO pageReqVO) {
+    public CommonResult<PageResult<PageUiComponentDO>> getPageUiComponentPage(@Valid PageUiComponentPageReqVO pageReqVO) {
         PageResult<PageUiComponentDO> pageResult = pageUiComponentService.getPageUiComponentPage(pageReqVO);
-        return success(BeanUtils.toBean(pageResult, PageUiComponentRespVO.class));
+        return success(pageResult);
     }
 
 }

+ 1 - 1
yudao-module-system/src/main/resources/mapper/RolePageMapper.xml

@@ -20,7 +20,7 @@
         <where>
             rp.deleted = 0
             <if test="vo.roleName != null and vo.roleName.trim != ''">
-                and r.naem like concat('%',#{vo.roleName},'%')
+                and r.name like concat('%',#{vo.roleName},'%')
             </if>
         </where>
         order by rp.id desc