lipenghui hai 2 semanas
pai
achega
63dc649f27
Modificáronse 16 ficheiros con 516 adicións e 61 borrados
  1. 6 0
      yudao-module-pms/yudao-module-pms-biz/pom.xml
  2. 149 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/FileUploadController.java
  3. 16 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/IotInfoController.java
  4. 11 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/IotTreeController.java
  5. 16 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/FileUploadVO.java
  6. 1 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotInfoClassifySaveReqVO.java
  7. 1 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotInfoPageReqVO.java
  8. 1 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotInfoRespVO.java
  9. 2 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotInfoSaveReqVO.java
  10. 1 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotTreeSaveReqVO.java
  11. 2 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/IotInfoDO.java
  12. 3 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/IotTreeDO.java
  13. 1 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/IotInfoService.java
  14. 291 57
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/IotInfoServiceImpl.java
  15. 1 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/IotTreeService.java
  16. 14 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/IotTreeServiceImpl.java

+ 6 - 0
yudao-module-pms/yudao-module-pms-biz/pom.xml

@@ -120,6 +120,12 @@
             <groupId>org.liquibase</groupId>
             <artifactId>liquibase-core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-infra-biz</artifactId>
+            <version>2.4.2-jdk8-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
 </project>

+ 149 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/FileUploadController.java

@@ -0,0 +1,149 @@
+package cn.iocoder.yudao.module.pms.controller.admin;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.exception.ErrorCode;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
+import cn.iocoder.yudao.module.infra.service.file.FileService;
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.annotation.security.PermitAll;
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+
+@RestController
+@RequestMapping("/rq/file")
+@Slf4j
+public class FileUploadController {
+
+    @Value("${file.upload-path}")
+    private String uploadPath;
+    @Resource
+    private FileService fileService;
+
+    @PostMapping("/upload")
+    @PermitAll
+    @TenantIgnore
+    public CommonResult<Map<String, Object>> uploadFiles(
+            @RequestParam("files") MultipartFile[] files,
+            @RequestParam(value = "isFolder", defaultValue = "false") boolean isFolder,
+            HttpServletRequest request) {
+
+        // 创建根目录(如果不存在)
+        File rootDir = new File(uploadPath);
+        if (!rootDir.exists()) {
+            rootDir.mkdirs();
+        }
+
+        List<Map<String, Object>> fileList = new ArrayList<>();
+        Map<String, Object> folderStructure = new HashMap<>();
+
+        try {
+            for (MultipartFile file : files) {
+                if (file.isEmpty()) {
+                    continue;
+                }
+
+                // 获取原始文件名(包含路径信息)
+                String originalFilename = file.getOriginalFilename();
+                if (StrUtil.isBlank(originalFilename)) {
+                    continue;
+                }
+
+//                // 构建文件保存路径
+                Path filePath = Paths.get(uploadPath, originalFilename);
+//
+//                // 创建父目录
+                File parentDir = filePath.getParent().toFile();
+                if (!parentDir.exists()) {
+                    parentDir.mkdirs();
+                }
+//
+//                // 保存文件
+//                file.transferTo(filePath.toFile());
+
+                // 记录文件信息
+                Map<String, Object> fileInfo = new HashMap<>();
+                fileInfo.put("name", FileUtil.getName(originalFilename));
+                String filePaths = fileService.createFile(FileUtil.getName(originalFilename), originalFilename, IoUtil.readBytes(file.getInputStream()));
+
+                fileInfo.put("path", originalFilename);
+                fileInfo.put("filePath", filePaths);
+                fileInfo.put("size", file.getSize());
+                fileInfo.put("isFolder", false);
+                fileList.add(fileInfo);
+
+                // 构建文件夹结构
+                buildFolderStructure(folderStructure, originalFilename);
+            }
+
+            Map<String, Object> result = new HashMap<>();
+            result.put("files", fileList);
+            result.put("folderStructure", folderStructure);
+            result.put("message", "上传成功");
+
+            System.out.println("------------------"+ JSON.toJSONString(result));
+            return CommonResult.success(result);
+
+        } catch (IOException e) {
+            log.error("文件上传失败", e);
+            return CommonResult.error(new ErrorCode(122, e.getMessage()));
+        }
+    }
+
+    /**
+     * 构建文件夹层级结构
+     */
+    private void buildFolderStructure(Map<String, Object> structure, String filePath) {
+        String[] pathParts = filePath.split("/");
+
+        // 如果是文件,最后一部分是文件名
+        boolean isFile = pathParts.length > 0 && FileUtil.isFile(filePath);
+        int depth = isFile ? pathParts.length - 1 : pathParts.length;
+
+//        Map<String, Object> currentLevel = structure;
+
+        for (int i = 0; i < depth; i++) {
+            String part = pathParts[i];
+            boolean isLastFolder = i == depth - 1;
+
+            if (!structure.containsKey(part)) {
+                Map<String, Object> newLevel = new HashMap<>();
+                newLevel.put("isFolder", true);
+                newLevel.put("children", new HashMap<>());
+
+                if (isLastFolder && isFile) {
+                    // 如果是文件的父文件夹,添加文件信息
+                    List<String> files = (List<String>) newLevel.getOrDefault("files", new ArrayList<>());
+                    files.add(pathParts[pathParts.length - 1]);
+                    newLevel.put("files", files);
+                }
+
+                structure.put(part, newLevel);
+            } else {
+                // 如果文件夹已存在,检查是否需要添加文件
+                if (isLastFolder && isFile) {
+                    Map<String, Object> existingLevel = (Map<String, Object>) structure.get(part);
+                    List<String> files = (List<String>) existingLevel.getOrDefault("files", new ArrayList<>());
+                    files.add(pathParts[pathParts.length - 1]);
+                    existingLevel.put("files", files);
+                }
+            }
+
+            // 进入下一级
+            structure = (Map<String, Object>) ((Map<String, Object>) structure.get(part)).get("children");
+        }
+    }
+}

+ 16 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/IotInfoController.java

@@ -105,7 +105,7 @@ public class IotInfoController {
             if (Objects.nonNull(e.getDeviceId())) {
                 IotDeviceDO iotDevice = iotDeviceService.getIotDevice(e.getDeviceId());
                 if (Objects.nonNull(iotDevice)) {
-                    vo.setDeviceName(iotDevice.getDeviceName());
+                    vo.setDeviceCode(iotDevice.getDeviceCode());
                 }
             }
             if (Objects.nonNull(e.getDeptId())) {
@@ -147,4 +147,19 @@ public class IotInfoController {
                         BeanUtils.toBean(list, IotInfoRespVO.class));
     }
 
+    @PostMapping("/all/content-file")
+    @Operation(summary = "获得资料库下的所有分类目录及文件")
+    @PreAuthorize("@ss.hasPermission('rq:iot-info:query')")
+    public CommonResult<List<IotInfoRespVO>> getAllContentFile(@Valid IotInfoPageReqVO pageReqVO) {
+        Long classId = pageReqVO.getClassId();
+        List<IotInfoRespVO> contentFiles = iotInfoService.getAllChildContentFile(classId).stream().filter(e ->{
+            if (StringUtils.isNotBlank(pageReqVO.getAllName())) {
+                return e.getFilename().contains(pageReqVO.getAllName());
+            } else {
+                return true;
+            }
+        }).collect(Collectors.toList());
+        return success(contentFiles);
+    }
+
 }

+ 11 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/IotTreeController.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.pms.controller.admin;
 
+import cn.hutool.core.collection.CollUtil;
 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;
@@ -150,4 +151,14 @@ public class IotTreeController {
         list.add(map);
         return success(list);
     }
+
+    @GetMapping("/device/{id}")
+    @PreAuthorize("@ss.hasPermission('rq:iot-tree:query')")
+    public CommonResult<Long> getDeviceTree(@PathVariable("id") Long deviceId) {
+        List<IotTreeDO> iotDeviceTree = iotTreeService.getIotDeviceTree(deviceId);
+        if (CollUtil.isEmpty(iotDeviceTree)) {
+            return success(null);
+        }
+        return success(iotDeviceTree.get(0).getId());
+    }
 }

+ 16 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/FileUploadVO.java

@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.module.pms.controller.admin.vo;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class FileUploadVO {
+
+    private List<Map<String, Object>> files;
+
+    private Map<String, Object> folderStructure;
+
+    private String message;
+}

+ 1 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotInfoClassifySaveReqVO.java

@@ -14,7 +14,7 @@ public class IotInfoClassifySaveReqVO {
     private Long id;
 
     @Schema(description = "父分类id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1691")
-    @NotNull(message = "父分类id不能为空")
+//    @NotNull(message = "父分类id不能为空")
     private Long parentId;
 
     @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")

+ 1 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotInfoPageReqVO.java

@@ -43,4 +43,5 @@ public class IotInfoPageReqVO extends PageParam {
     @Schema(description = "创建id")
     private String creator;
 
+    private String allName;
 }

+ 1 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotInfoRespVO.java

@@ -52,7 +52,7 @@ public class IotInfoRespVO {
     private String fileSize;
 
     @Schema(description = "设备名称")
-    private String deviceName;
+    private String deviceCode;
 
     @Schema(description = "部门名称")
     private String deptName;

+ 2 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotInfoSaveReqVO.java

@@ -47,5 +47,7 @@ public class IotInfoSaveReqVO {
 
     private String type;
 
+    private List<FileUploadVO> folderTree;
+
     private String folderJson;
 }

+ 1 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotTreeSaveReqVO.java

@@ -13,7 +13,7 @@ public class IotTreeSaveReqVO {
     private Long id;
 
     @Schema(description = "原id", requiredMode = Schema.RequiredMode.REQUIRED, example = "19643")
-    @NotNull(message = "原id不能为空")
+//    @NotNull(message = "原id不能为空")
     private Long originId;
 
     @Schema(description = "父分类id", requiredMode = Schema.RequiredMode.REQUIRED, example = "3195")

+ 2 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/IotInfoDO.java

@@ -57,4 +57,6 @@ public class IotInfoDO extends BaseDO {
      */
     private String remark;
 
+    private String deviceCode;
+    private String deptName;
 }

+ 3 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/IotTreeDO.java

@@ -55,4 +55,7 @@ public class IotTreeDO extends BaseDO {
 
     private Long deptId;
 
+    private String deviceCode;
+    private String deptName;
+
 }

+ 1 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/IotInfoService.java

@@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.pms.dal.dataobject.IotInfoDO;
  */
 public interface IotInfoService {
     List<IotInfoRespVO> getChildContentFile(Long classId);
+    List<IotInfoRespVO> getAllChildContentFile(Long classId);
     /**
      * 创建资料
      *

+ 291 - 57
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/IotInfoServiceImpl.java

@@ -1,29 +1,35 @@
 package cn.iocoder.yudao.module.pms.service;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.io.FileUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.pms.controller.admin.vo.*;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotInfoPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotInfoRespVO;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotInfoSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotTreeListReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.IotInfoClassifyDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.IotInfoDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.IotTreeDO;
-import cn.iocoder.yudao.module.pms.dal.mysql.IotInfoClassifyMapper;
+import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.IotInfoMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.IotTreeMapper;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableList;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -37,6 +43,7 @@ import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_INFO_NOT_E
  */
 @Service
 @Validated
+@Slf4j
 public class IotInfoServiceImpl implements IotInfoService {
 
     @Resource
@@ -51,45 +58,49 @@ public class IotInfoServiceImpl implements IotInfoService {
     private DeptApi deptApi;
     @Autowired
     private IotTreeMapper iotTreeMapper;
+    @Autowired
+    private IotDeviceMapper iotDeviceMapper;
 
     @Override
     public List<IotInfoRespVO> getChildContentFile(Long classId) {
         List<IotTreeDO> contents = iotTreeMapper.selectList("parent_id", classId);
         List<IotInfoDO> files = iotInfoMapper.selectList("class_id", classId);
+        List<IotInfoRespVO> contentVos = dealFileVo(contents, files);
+        return contentVos;
+    }
+
+    private List<IotInfoRespVO> dealFileVo(List<IotTreeDO> contents, List<IotInfoDO> files){
         List<IotInfoRespVO> contentVos = contents.stream().map(e -> {
             IotInfoRespVO iotInfoRespVO = new IotInfoRespVO();
             iotInfoRespVO.setFilename(e.getName());
             iotInfoRespVO.setId(e.getId());
             iotInfoRespVO.setFileType("content");//设置为文件夹
-//            if (Objects.nonNull(e.get())) {
-//                IotDeviceDO iotDevice = iotDeviceService.getIotDevice(e.getDeviceId());
-//                if (Objects.nonNull(iotDevice)) {
-//                    iotInfoRespVO.setDeviceName(iotDevice.getDeviceName());
+//            if (Objects.nonNull(e.getDeptId())) {
+//                DeptRespDTO dept = deptApi.getDept(e.getDeptId());
+//                if (Objects.nonNull(dept)) {
+//                    iotInfoRespVO.setDeptName(dept.getName());
 //                }
 //            }
-            if (Objects.nonNull(e.getDeptId())) {
-                DeptRespDTO dept = deptApi.getDept(e.getDeptId());
-                if (Objects.nonNull(dept)) {
-                    iotInfoRespVO.setDeptName(dept.getName());
-                }
-            }
+            iotInfoRespVO.setDeptName(e.getDeptName());
             return iotInfoRespVO;
         }).collect(Collectors.toList());
         List<IotInfoRespVO> fileVos = files.stream().map(e -> {
             IotInfoRespVO iotInfoRespVO = new IotInfoRespVO();
             BeanUtils.copyProperties(e, iotInfoRespVO);
-            if (Objects.nonNull(e.getDeviceId())) {
-                IotDeviceDO iotDevice = iotDeviceService.getIotDevice(e.getDeviceId());
-                if (Objects.nonNull(iotDevice)) {
-                    iotInfoRespVO.setDeviceName(iotDevice.getDeviceName());
-                }
-            }
-            if (Objects.nonNull(e.getDeptId())) {
-                DeptRespDTO dept = deptApi.getDept(e.getDeptId());
-                if (Objects.nonNull(dept)) {
-                    iotInfoRespVO.setDeptName(dept.getName());
-                }
-            }
+//            if (Objects.nonNull(e.getDeviceId())) {
+//                IotDeviceDO iotDevice = iotDeviceService.getIotDevice(e.getDeviceId());
+//                if (Objects.nonNull(iotDevice)) {
+//                    iotInfoRespVO.setDeviceName(iotDevice.getDeviceName());
+//                }
+//            }
+//            if (Objects.nonNull(e.getDeptId())) {
+//                DeptRespDTO dept = deptApi.getDept(e.getDeptId());
+//                if (Objects.nonNull(dept)) {
+//                    iotInfoRespVO.setDeptName(dept.getName());
+//                }
+//            }
+            iotInfoRespVO.setDeviceCode(e.getDeviceCode());
+            iotInfoRespVO.setDeptName(e.getDeptName());
             String docOrPdf = StringUtils.substringAfterLast(iotInfoRespVO.getFilename(), ".");
             iotInfoRespVO.setFileClassify(docOrPdf);
             iotInfoRespVO.setFileType("file");
@@ -99,41 +110,76 @@ public class IotInfoServiceImpl implements IotInfoService {
         return contentVos;
     }
 
+
     @Override
+    public List<IotInfoRespVO> getAllChildContentFile(Long classId) {
+        List<IotTreeDO> contents = iotTreeService.getChildTreeList(ImmutableList.of(classId));
+//        if (CollUtil.isNotEmpty(contents)) {
+            List<Long> contentIds = contents.stream().map(IotTreeDO::getId).collect(Collectors.toList());
+            IotInfoPageReqVO infoPageReqVO = new IotInfoPageReqVO();
+            infoPageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            List<IotInfoDO> files = iotInfoMapper.selectPage(infoPageReqVO, contentIds).getList();
+//        }
+        List<IotInfoRespVO> infoRespVOS = dealFileVo(contents, files);
+        return infoRespVOS;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
     public void createIotInfo(IotInfoSaveReqVO createReqVO) {
         // 插入
-        if (CollUtil.isEmpty(createReqVO.getFileList())) {
-            throw exception(IOT_INFO_NOT_EXISTS);
-        }
+//        if (CollUtil.isEmpty(createReqVO.getFileList())) {
+//            throw exception(IOT_INFO_NOT_EXISTS);
+//        }
+        Long deptId;
+        Long deviceId;
         Long classId = createReqVO.getClassId();
-        IotDeviceDO iotDevice = iotDeviceService.getIotDevice(createReqVO.getDeviceId());
-        List<IotInfoDO> collect = createReqVO.getFileList().stream().map(e -> {
-            IotInfoDO iotInfo = BeanUtils.toBean(createReqVO, IotInfoDO.class);
-            iotInfo.setFilename(StringUtils.substringAfterLast(e.get("url"), "/"));
-            iotInfo.setFilePath(e.get("url"));
-            iotInfo.setDeptId(iotDevice.getDeptId());
-            long size = Long.parseLong(e.get("size"));
-            double mb = size / (1024.0 * 1024.0);
-            iotInfo.setFileSize(String.format("%.2f MB", mb));
-            iotInfo.setDeleted(false);
-            if ("book".equals(createReqVO.getType())) {
-                IotInfoClassifyDO classify = iotInfoClassifyService.getIotInfoClassify(classId);
-                //如果是设备的话
-                IotTreeListReqVO reqVO = new IotTreeListReqVO();
-                if (classify.getParentId()==0) {
-                    reqVO.setType("device").setOriginId(classify.getDeviceId());
-                } else {
-                    reqVO.setType("file").setOriginId(classId);
-                }
-                List<IotTreeDO> iotTreeList = iotTreeService.getIotTreeList(reqVO);
-                if (CollUtil.isNotEmpty(iotTreeList)) {
-                    iotInfo.setClassId(iotTreeList.get(0).getId());
-                }
+        String deviceCode = "";
+        String deptName = "";
+        if (Objects.nonNull(createReqVO.getDeviceId())) {
+            IotDeviceDO iotDevice = iotDeviceService.getIotDevice(createReqVO.getDeviceId());
+            deptId = iotDevice.getDeptId();
+            deviceCode = iotDevice.getDeviceCode();
+        } else {
+            IotTreeDO iotTreeDO = iotTreeMapper.selectById(createReqVO.getClassId());
+            deptId = iotTreeDO.getDeptId();
+        }
+        if (Objects.nonNull(deptId)) {
+            DeptRespDTO dept = deptApi.getDept(deptId);
+            if (Objects.nonNull(dept)) {
+                deptName = dept.getName();
             }
-            return iotInfo;
-        }).collect(Collectors.toList());
+        }
+
+        importFileTree(createReqVO.getFolderJson(), classId, deptId, createReqVO.getDeviceId(), deviceCode, deptName);
 
-        iotInfoMapper.insert(collect);
+//        List<IotInfoDO> collect = createReqVO.getFileList().stream().map(e -> {
+//            IotInfoDO iotInfo = BeanUtils.toBean(createReqVO, IotInfoDO.class);
+//            iotInfo.setFilename(StringUtils.substringAfterLast(e.get("url"), "/"));
+//            iotInfo.setFilePath(e.get("url"));
+//            iotInfo.setDeptId(iotDevice.getDeptId());
+//            long size = Long.parseLong(e.get("size"));
+//            double mb = size / (1024.0 * 1024.0);
+//            iotInfo.setFileSize(String.format("%.2f MB", mb));
+//            iotInfo.setDeleted(false);
+//            if ("book".equals(createReqVO.getType())) {
+//                IotInfoClassifyDO classify = iotInfoClassifyService.getIotInfoClassify(classId);
+//                //如果是设备的话
+//                IotTreeListReqVO reqVO = new IotTreeListReqVO();
+//                if (classify.getParentId()==0) {
+//                    reqVO.setType("device").setOriginId(classify.getDeviceId());
+//                } else {
+//                    reqVO.setType("file").setOriginId(classId);
+//                }
+//                List<IotTreeDO> iotTreeList = iotTreeService.getIotTreeList(reqVO);
+//                if (CollUtil.isNotEmpty(iotTreeList)) {
+//                    iotInfo.setClassId(iotTreeList.get(0).getId());
+//                }
+//            }
+//            return iotInfo;
+//        }).collect(Collectors.toList());
+
+//        iotInfoMapper.insert(collect);
     }
     @Override
     public void updateIotInfo(IotInfoSaveReqVO updateReqVO) {
@@ -228,4 +274,192 @@ public class IotInfoServiceImpl implements IotInfoService {
     }
 
 
+    private final ObjectMapper objectMapper = new ObjectMapper();
+
+
+
+    public void importFileTree(String jsonData, Long parentId, Long deptId, Long deviceId, String deviceCode, String deptName) {
+        try {
+            // 解析JSON数组
+            JsonNode rootNode = objectMapper.readTree(jsonData);
+
+            if (rootNode.isArray()) {
+                for (JsonNode itemNode : rootNode) {
+                    // 处理文件夹结构
+                    JsonNode folderStructureNode = itemNode.get("folderStructure");
+                    Long fileClassId = null;
+                    if (folderStructureNode != null) {
+                        fileClassId = processFolderStructure(folderStructureNode, parentId, deptId, deviceCode, deptName);
+                    }
+
+                    // todo 处理文件
+                    JsonNode filesNode = itemNode.get("files");
+                    if (filesNode != null && filesNode.isArray()&&Objects.nonNull(fileClassId)) {
+                        processFiles(filesNode, parentId, fileClassId, deviceId, deptId, deviceCode, deptName);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("导入文件树结构失败", e);
+            throw new RuntimeException("导入文件树结构失败", e);
+        }
+    }
+
+    /**
+     * 处理文件夹结构
+     */
+//    private void processFolderStructure(JsonNode folderStructureNode, Long parentId, Long deptId) {
+//        Iterator<String> fieldNames = folderStructureNode.fieldNames();
+//
+//        while (fieldNames.hasNext()) {
+//            String folderName = fieldNames.next();
+//            JsonNode folderNode = folderStructureNode.get(folderName);
+//
+//            if (folderName.contains(".")) {
+//                break;
+//            }
+//            IotTreeDO iotTreeDO = iotTreeMapper.selectOne("name", folderName, "parent_id", parentId);
+//
+//
+//            Long currentNodeId;
+//            if (iotTreeDO != null) {
+//                currentNodeId = iotTreeDO.getId();
+//            } else {
+//                // 插入当前文件夹节点
+////                IotTreeDO folder = new IotTreeDO(folderName, parentId);
+////                save(folder);
+//                IotTreeDO folder = new IotTreeDO();
+//                folder.setParentId(parentId);
+//                folder.setName(folderName);
+//                folder.setDeleted(false);
+//                folder.setType("file");
+//                folder.setDeptId(deptId);
+//                iotTreeMapper.insert(folder);
+//                currentNodeId = folder.getId();
+//            }
+//
+//            // 递归处理子文件夹
+//            JsonNode childrenNode = folderNode.get("children");
+//            if (childrenNode != null && !childrenNode.isNull() && !childrenNode.isEmpty()) {
+//                processFolderStructure(childrenNode, currentNodeId, deptId);
+//            }
+//        }
+//    }
+
+    /**
+     * 处理文件夹结构并递归创建节点,当遇到包含"."的文件夹名时返回其parentId
+     * @param folderStructureNode 文件夹结构的JSON节点
+     * @param parentId 父节点ID
+     * @param deptId 部门ID
+     * @return 遇到包含"."的文件夹时返回其parentId,否则返回null
+     */
+    private Long processFolderStructure(JsonNode folderStructureNode, Long parentId, Long deptId, String deviceCode, String deptName) {
+        Iterator<String> fieldNames = folderStructureNode.fieldNames();
+
+        while (fieldNames.hasNext()) {
+            String folderName = fieldNames.next();
+            JsonNode folderNode = folderStructureNode.get(folderName);
+
+            // 检查文件夹名是否包含".",如果是则返回当前parentId
+            if (folderName.contains(".")) {
+                return parentId; // 返回当前节点的父ID
+            }
+
+            // 查询是否已存在同名同父节点的记录
+            IotTreeDO iotTreeDO = iotTreeMapper.selectOne("name", folderName, "parent_id", parentId);
+
+            Long currentNodeId;
+            if (iotTreeDO != null) {
+                currentNodeId = iotTreeDO.getId();
+            } else {
+                // 创建新节点
+                IotTreeDO folder = new IotTreeDO();
+                folder.setParentId(parentId);
+                folder.setName(folderName);
+                folder.setDeleted(false);
+                folder.setType("file");
+                folder.setDeptId(deptId);
+                folder.setDeviceCode(deviceCode);
+                folder.setDeptName(deptName);
+                iotTreeMapper.insert(folder);
+                currentNodeId = folder.getId();
+            }
+
+            // 递归处理子文件夹
+            JsonNode childrenNode = folderNode.get("children");
+            if (childrenNode != null && !childrenNode.isNull() && !childrenNode.isEmpty()) {
+                // 递归调用,如果子节点处理中返回了parentId,则向上传递
+                Long result = processFolderStructure(childrenNode, currentNodeId, deptId, deviceCode, deptName);
+                if (result != null) {
+                    return result; // 子节点处理中遇到了目标,返回结果
+                }
+            }
+        }
+
+        // 正常处理完所有节点,未遇到包含"."的文件夹
+        return null;
+    }
+
+    /**
+     * 处理文件
+     */
+    private void processFiles(JsonNode filesNode, Long rootParentId,Long fileClassId, Long deviceId, Long deptId, String deviceCode, String deptName) {
+        for (JsonNode fileNode : filesNode) {
+            String path = fileNode.get("path").asText();
+            String filePath = fileNode.get("filePath").asText();
+            String fileName = fileNode.get("name").asText();
+            String size = fileNode.get("size").asText();
+
+            // 根据路径确定父文件夹ID
+            String[] pathParts = path.split("/");
+            Long parentId = rootParentId;
+
+            // 逐级查找或创建父文件夹
+            for (int i = 0; i < pathParts.length - 1; i++) {
+                String folderName = pathParts[i];
+                parentId = findOrCreateFolder(folderName, parentId);
+            }
+
+            // 检查文件是否已存在
+            IotInfoDO iotInfoDO = iotInfoMapper.selectOne("filename", fileName, "class_id", fileClassId);
+            if (iotInfoDO == null) {
+                IotInfoDO info = new IotInfoDO();
+                info.setDeviceId(deviceId);
+                info.setDeptId(deptId);
+                info.setClassId(fileClassId);
+                info.setFilename(fileName);
+                info.setDeleted(false);
+                info.setDeviceCode(deviceCode);
+                info.setDeptName(deptName);
+                info.setFileType("file");
+                if (fileName.contains("jpg")||fileName.contains("jpeg")||fileName.contains("png")||fileName.contains("gif")) {
+                    info.setFileType("pic");
+                }
+                info.setFilePath(filePath);
+                if (StringUtils.isNotBlank(size)&&!"null".equals(size)) {
+                    long fileSize = Long.parseLong(size);
+                    double mb = fileSize / (1024.0 * 1024.0);
+                    info.setFileSize(String.format("%.2f MB", mb));
+                }
+                iotInfoMapper.insert(info);
+            }
+        }
+    }
+
+    /**
+     * 查找或创建文件夹
+     */
+    private Long findOrCreateFolder(String folderName, Long parentId) {
+        IotTreeDO folder = iotTreeMapper.selectOne("name", folderName, "parent_id", parentId);
+
+        if (folder == null) {
+            folder.setParentId(parentId);
+            folder.setName(folderName);
+            folder.setDeleted(false);
+            folder.setType("file");
+            iotTreeMapper.insert(folder);
+        }
+
+        return folder.getId();
+    }
 }

+ 1 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/IotTreeService.java

@@ -21,6 +21,7 @@ import java.util.List;
  * @author 芋道源码
  */
 public interface IotTreeService {
+    List<IotTreeDO> getIotDeviceTree(Long deviceId);
     List<IotTreeDO> getIotTreeList(IotTreeListReqVO reqVO);
     void addDeptDeal(DeptDO deptDO);
     void updateDeptDeal(DeptDO deptDO);

+ 14 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/IotTreeServiceImpl.java

@@ -50,6 +50,15 @@ public class IotTreeServiceImpl implements IotTreeService {
     @Autowired
     private IotInfoClassifyMapper iotInfoClassifyMapper;
 
+    @Override
+    public List<IotTreeDO> getIotDeviceTree(Long deviceId) {
+        IotTreeListReqVO reqVO = new IotTreeListReqVO();
+        reqVO.setType("device");
+        reqVO.setOriginId(deviceId);
+        List<IotTreeDO> iotTreeDOS = iotTreeMapper.selectList(reqVO);
+        return iotTreeDOS;
+    }
+
     @Override
     public List<IotTreeDO> getIotTreeList(IotTreeListReqVO reqVO) {
         List<IotTreeDO> list = iotTreeMapper.selectList(reqVO);
@@ -95,6 +104,9 @@ public class IotTreeServiceImpl implements IotTreeService {
     public Long createIotTree(IotTreeSaveReqVO createReqVO) {
         // 插入
         IotTreeDO iotTree = BeanUtils.toBean(createReqVO, IotTreeDO.class);
+        if ("file".equals(createReqVO.getType())&&Objects.nonNull(createReqVO.getParentId())){
+
+        }
         iotTreeMapper.insert(iotTree);
         // 返回
         return iotTree.getId();
@@ -113,6 +125,8 @@ public class IotTreeServiceImpl implements IotTreeService {
     public void deleteIotTree(Long id) {
         // 校验存在
         validateIotTreeExists(id);
+
+
         // 删除
         iotTreeMapper.deleteById(id);
     }