Procházet zdrojové kódy

服务测试记录

ZhuDeKang před 5 měsíci
rodič
revize
71aa417b62
25 změnil soubory, kde provedl 956 přidání a 148 odebrání
  1. 1 1
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdAppFlowController.java
  2. 1 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdDataSetApiController.java
  3. 20 16
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdDataSetFileController.java
  4. 5 5
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtServiceController.java
  5. 101 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtServiceRunLogController.java
  6. 7 5
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtTreeCateController.java
  7. 0 1
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/database/DynamicDataSourceManager.java
  8. 1 5
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/PtServiceLog.java
  9. 135 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/PtServiceRunLog.java
  10. 21 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/vo/MdDataSetSqlVo.java
  11. 37 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/vo/PtServiceRunLogVo.java
  12. 65 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/mapper/PtServiceRunLogMapper.java
  13. 4 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IMdDataSetFileService.java
  14. 61 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IPtServiceRunLogService.java
  15. 3 2
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/MdAppFlowServiceImpl.java
  16. 29 21
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/MdDataSetFileServiceImpl.java
  17. 93 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/PtServiceRunLogServiceImpl.java
  18. 2 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/TinyflowUtil.java
  19. 1 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/node/PrintNode.java
  20. 38 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/node/SQLNode.java
  21. 2 4
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/node/ServiceNode.java
  22. 24 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/parser/SQLNodeParser.java
  23. 83 0
      ruoyi-api-patform/src/main/resources/mapper/interfaces/PtServiceRunLogMapper.xml
  24. 166 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/ExcelParserUtil.java
  25. 56 88
      ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java

+ 1 - 1
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdAppFlowController.java

@@ -101,7 +101,7 @@ public class MdAppFlowController extends BaseController
     @PostMapping("/runFlow")
     public AjaxResult runFlow(@RequestBody MdAppFlow appFlow){
 
-
+        System.out.println(appFlow.getFlowGraph());
         return success(mdAppFlowService.runFlow(appFlow));
     }
 

+ 1 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdDataSetApiController.java

@@ -3,6 +3,7 @@ package com.ruoyi.interfaces.controller;
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 
+import com.ruoyi.interfaces.domain.PtService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;

+ 20 - 16
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdDataSetFileController.java

@@ -1,5 +1,6 @@
 package com.ruoyi.interfaces.controller;
 
+import java.util.HashMap;
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 
@@ -21,14 +22,13 @@ import com.ruoyi.common.core.page.TableDataInfo;
 
 /**
  * 文件数据集Controller
- * 
+ *
  * @author 朱得糠
  * @date 2025-09-02
  */
 @RestController
 @RequestMapping("/data/set/file")
-public class MdDataSetFileController extends BaseController
-{
+public class MdDataSetFileController extends BaseController {
     @Autowired
     private IMdDataSetFileService mdDataSetFileService;
 
@@ -36,8 +36,7 @@ public class MdDataSetFileController extends BaseController
      * 查询文件数据集列表
      */
     @GetMapping("/list")
-    public TableDataInfo list(MdDataSetFile mdDataSetFile)
-    {
+    public TableDataInfo list(MdDataSetFile mdDataSetFile) {
         startPage();
         List<MdDataSetFile> list = mdDataSetFileService.selectMdDataSetFileList(mdDataSetFile);
         return getDataTable(list);
@@ -47,8 +46,7 @@ public class MdDataSetFileController extends BaseController
      * 导出文件数据集列表
      */
     @PostMapping("/export")
-    public void export(HttpServletResponse response, MdDataSetFile mdDataSetFile)
-    {
+    public void export(HttpServletResponse response, MdDataSetFile mdDataSetFile) {
         List<MdDataSetFile> list = mdDataSetFileService.selectMdDataSetFileList(mdDataSetFile);
         ExcelUtil<MdDataSetFile> util = new ExcelUtil<MdDataSetFile>(MdDataSetFile.class);
         util.exportExcel(response, list, "文件数据集数据");
@@ -58,8 +56,7 @@ public class MdDataSetFileController extends BaseController
      * 获取文件数据集详细信息
      */
     @GetMapping(value = "/{dcCode}")
-    public AjaxResult getInfo(@PathVariable("dcCode") String dcCode)
-    {
+    public AjaxResult getInfo(@PathVariable("dcCode") String dcCode) {
         return success(mdDataSetFileService.selectMdDataSetFileByDcCode(dcCode));
     }
 
@@ -67,8 +64,7 @@ public class MdDataSetFileController extends BaseController
      * 新增文件数据集
      */
     @PostMapping
-    public AjaxResult add(@RequestBody MdDataSetFile mdDataSetFile)
-    {
+    public AjaxResult add(@RequestBody MdDataSetFile mdDataSetFile) {
         mdDataSetFileService.deleteMdDataSetFileByDcCode(mdDataSetFile.getDcCode());
         return toAjax(mdDataSetFileService.insertMdDataSetFile(mdDataSetFile));
     }
@@ -77,17 +73,25 @@ public class MdDataSetFileController extends BaseController
      * 修改文件数据集
      */
     @PutMapping
-    public AjaxResult edit(@RequestBody MdDataSetFile mdDataSetFile)
-    {
+    public AjaxResult edit(@RequestBody MdDataSetFile mdDataSetFile) {
         return toAjax(mdDataSetFileService.updateMdDataSetFile(mdDataSetFile));
     }
 
     /**
      * 删除文件数据集
      */
-	@DeleteMapping("/{ids}")
-    public AjaxResult remove(@PathVariable Long[] ids)
-    {
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
         return toAjax(mdDataSetFileService.deleteMdDataSetFileByIds(ids));
     }
+
+    @PostMapping("/query")
+    public AjaxResult query(@RequestBody MdDataSetFile mdDataSetFile) {
+        try {
+            List<HashMap<String, Object>> hashMaps = mdDataSetFileService.queryFileData(mdDataSetFile);
+            return AjaxResult.success(hashMaps);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
 }

+ 5 - 5
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtServiceController.java

@@ -48,7 +48,7 @@ public class PtServiceController extends BaseController {
     private PtServiceFileService ptServiceFileService;
 
     @Autowired
-    private IPtServiceLogService ptServiceLogService;
+    private IPtServiceRunLogService serviceRunLogService;
 
     @ApiOperation("添加数据")
     @PostMapping(value = "/save")
@@ -188,9 +188,9 @@ public class PtServiceController extends BaseController {
     @PostMapping("/testRun")
     public AjaxResult testRun(@RequestBody PtService ptService) throws IOException {
 
-        PtServiceLog ptServiceLog = new PtServiceLog(ptService);
+        PtServiceRunLog ptServiceLog = new PtServiceRunLog(ptService);
         Date nowDate = DateUtils.getNowDate();
-        ptServiceLog.setTm(nowDate);
+        ptServiceLog.setRunTm(nowDate);
         String s = "";
         try {
 
@@ -201,8 +201,8 @@ public class PtServiceController extends BaseController {
 
         ptServiceLog.setExecTm(
                 DateUtils.getNowDate().getTime() - nowDate.getTime());
-        ptServiceLog.setReturnText(s);
-        ptServiceLogService.insertPtServiceLog(ptServiceLog);
+        ptServiceLog.setReturnData(s);
+        serviceRunLogService.insertPtServiceRunLog(ptServiceLog);
         return success(s);
     }
 

+ 101 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtServiceRunLogController.java

@@ -0,0 +1,101 @@
+package com.ruoyi.interfaces.controller;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import com.ruoyi.interfaces.domain.vo.PtServiceRunLogVo;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.interfaces.domain.PtServiceRunLog;
+import com.ruoyi.interfaces.service.IPtServiceRunLogService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 服务运行logController
+ * 
+ * @author 朱得糠
+ * @date 2025-09-23
+ */
+@RestController
+@RequestMapping("/service/run/log")
+public class PtServiceRunLogController extends BaseController
+{
+    @Autowired
+    private IPtServiceRunLogService ptServiceRunLogService;
+
+    /**
+     * 查询服务运行log列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo list(PtServiceRunLog ptServiceRunLog)
+    {
+        startPage();
+        ArrayList<PtServiceRunLogVo> data = new ArrayList<>();
+        List<PtServiceRunLog> list = ptServiceRunLogService.selectPtServiceRunLogList(ptServiceRunLog);
+        for (PtServiceRunLog serviceRunLog : list) {
+            data.add(new PtServiceRunLogVo(serviceRunLog));
+        }
+        return getDataTable(data);
+    }
+
+    /**
+     * 导出服务运行log列表
+     */
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, PtServiceRunLog ptServiceRunLog)
+    {
+        List<PtServiceRunLog> list = ptServiceRunLogService.selectPtServiceRunLogList(ptServiceRunLog);
+        ExcelUtil<PtServiceRunLog> util = new ExcelUtil<PtServiceRunLog>(PtServiceRunLog.class);
+        util.exportExcel(response, list, "服务运行log数据");
+    }
+
+    /**
+     * 获取服务运行log详细信息
+     */
+    @GetMapping(value = "/{logId}")
+    public AjaxResult getInfo(@PathVariable("logId") Long logId)
+    {
+        return success(ptServiceRunLogService.selectPtServiceRunLogByLogId(logId));
+    }
+
+    /**
+     * 新增服务运行log
+     */
+    @PostMapping
+    public AjaxResult add(@RequestBody PtServiceRunLog ptServiceRunLog)
+    {
+        return toAjax(ptServiceRunLogService.insertPtServiceRunLog(ptServiceRunLog));
+    }
+
+    /**
+     * 修改服务运行log
+     */
+    @PutMapping
+    public AjaxResult edit(@RequestBody PtServiceRunLog ptServiceRunLog)
+    {
+        return toAjax(ptServiceRunLogService.updatePtServiceRunLog(ptServiceRunLog));
+    }
+
+    /**
+     * 删除服务运行log
+     */
+	@DeleteMapping("/{logIds}")
+    public AjaxResult remove(@PathVariable Long[] logIds)
+    {
+        return toAjax(ptServiceRunLogService.deletePtServiceRunLogByLogIds(logIds));
+    }
+}

+ 7 - 5
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtTreeCateController.java

@@ -119,7 +119,6 @@ public class PtTreeCateController extends BaseController {
         }
 
 
-
         return success(ptTreeCateService.buildDataTreeSelect(ptTreeCates));
     }
 
@@ -159,17 +158,20 @@ public class PtTreeCateController extends BaseController {
      * @return
      */
     @GetMapping(value = "/modelTreeSelect")
-    public AjaxResult modelTreeSelect(PtTreeCate ptTreeCate)    {
+    public AjaxResult modelTreeSelect(PtTreeCate ptTreeCate) {
         ptTreeCate.setTreeType("MODEL");
         String level = StringUtils.isNull(ptTreeCate.getParams().get("level")) ? "3" : ptTreeCate.getParams().get("level").toString();
+        String devkind = StringUtils.isNull(ptTreeCate.getParams().get("devkind")) ? null : ptTreeCate.getParams().get("devkind").toString();
 
         List<PtTreeCate> ptTreeCates = ptTreeCateService.selectPtTreeCateList(ptTreeCate).stream().peek(item -> item.setNodeType("TREE")).collect(Collectors.toList());
         if (level.equals("2") || level.equals("3")) {
-            List<MdModelInfo> mdModelInfos = mdModelInfoService.selectMdModelInfoList(new MdModelInfo());
+            MdModelInfo modelPar = new MdModelInfo();
+            modelPar.setDevkind(devkind);
+            List<MdModelInfo> mdModelInfos = mdModelInfoService.selectMdModelInfoList(modelPar);
             for (MdModelInfo mdModelInfo : mdModelInfos) {
                 if (StringUtils.isNotNull(mdModelInfo.getMdid()) && StringUtils.isNotNull(mdModelInfo.getCateid())
                         && StringUtils.isNotNull(mdModelInfo.getName())) {
-                    ptTreeCates.add(new PtTreeCate(mdModelInfo.getMdid(), mdModelInfo.getCateid(), mdModelInfo.getName(), "MODEL",null));
+                    ptTreeCates.add(new PtTreeCate(mdModelInfo.getMdid(), mdModelInfo.getCateid(), mdModelInfo.getName(), "MODEL", null));
                 }
             }
         }
@@ -179,7 +181,7 @@ public class PtTreeCateController extends BaseController {
                 if (StringUtils.isNotNull(ptService.getSrvId()) &&
                         StringUtils.isNotNull(ptService.getMdid()) &&
                         StringUtils.isNotNull(ptService.getName())) {
-                    ptTreeCates.add(new PtTreeCate(ptService.getSrvId(), ptService.getMdid(), ptService.getName(), "SERVICE",ptService));
+                    ptTreeCates.add(new PtTreeCate(ptService.getSrvId(), ptService.getMdid(), ptService.getName(), "SERVICE", ptService));
                 }
             }
         }

+ 0 - 1
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/database/DynamicDataSourceManager.java

@@ -214,7 +214,6 @@ public class DynamicDataSourceManager {
         if (!PAGINATION_SQL_TEMPLATES.containsKey(databaseType)) {
             throw new IllegalArgumentException("不支持的数据库类型: " + databaseType);
         }
-
         String template = PAGINATION_SQL_TEMPLATES.get(databaseType);
 
         // 计算起始位置

+ 1 - 5
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/PtServiceLog.java

@@ -81,11 +81,7 @@ public class PtServiceLog extends BaseEntity
     private String serviceName;
 
 
-    public PtServiceLog(PtService ptService) {
-       this.serId=ptService.getSrvId();
-       this.mdId=ptService.getMdid();
-       this.senText=JsonUtils.objectToJson(ptService);
-    }
+
 
     public PtServiceLog(Long logId, String serId, String mdId, Date tm, String senText, String returnText, Long execTm) {
         this.logId = logId;

+ 135 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/PtServiceRunLog.java

@@ -0,0 +1,135 @@
+package com.ruoyi.interfaces.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.utils.JsonUtils;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 服务运行log对象 pt_service_run_log
+ * 
+ * @author 朱得糠
+ * @date 2025-09-23
+ */
+public class PtServiceRunLog extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** id */
+    @Excel(name = "id")
+    private Long logId;
+
+    /** 服务id */
+    @Excel(name = "服务id")
+    private String serId;
+
+    /** 模型id */
+    @Excel(name = "模型id")
+    private String mdId;
+
+    /** 请求时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "请求时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date runTm;
+
+    /** 请求参数 */
+    @Excel(name = "请求参数")
+    private String senParam;
+
+    /** 返回信息 */
+    @Excel(name = "返回信息")
+    private String returnData;
+
+    /** 请求耗时(毫秒) */
+    @Excel(name = "请求耗时", readConverterExp = "毫=秒")
+    private Long execTm;
+
+    public PtServiceRunLog(PtService ptService) {
+        this.serId=ptService.getSrvId();
+        this.mdId=ptService.getMdid();
+        this.senParam= JsonUtils.objectToJson(ptService.getParams());
+    }
+
+    public PtServiceRunLog() {
+    }
+
+    public void setLogId(Long logId)
+    {
+        this.logId = logId;
+    }
+
+    public Long getLogId() 
+    {
+        return logId;
+    }
+    public void setSerId(String serId) 
+    {
+        this.serId = serId;
+    }
+
+    public String getSerId() 
+    {
+        return serId;
+    }
+    public void setMdId(String mdId) 
+    {
+        this.mdId = mdId;
+    }
+
+    public String getMdId() 
+    {
+        return mdId;
+    }
+    public void setRunTm(Date runTm) 
+    {
+        this.runTm = runTm;
+    }
+
+    public Date getRunTm() 
+    {
+        return runTm;
+    }
+    public void setSenParam(String senParam) 
+    {
+        this.senParam = senParam;
+    }
+
+    public String getSenParam() 
+    {
+        return senParam;
+    }
+    public void setReturnData(String returnData) 
+    {
+        this.returnData = returnData;
+    }
+
+    public String getReturnData() 
+    {
+        return returnData;
+    }
+    public void setExecTm(Long execTm) 
+    {
+        this.execTm = execTm;
+    }
+
+    public Long getExecTm() 
+    {
+        return execTm;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("logId", getLogId())
+            .append("serId", getSerId())
+            .append("mdId", getMdId())
+            .append("runTm", getRunTm())
+            .append("senParam", getSenParam())
+            .append("returnData", getReturnData())
+            .append("execTm", getExecTm())
+            .toString();
+    }
+}

+ 21 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/vo/MdDataSetSqlVo.java

@@ -0,0 +1,21 @@
+package com.ruoyi.interfaces.domain.vo;
+
+import com.ruoyi.interfaces.domain.MdDataSetParam;
+import com.ruoyi.interfaces.domain.MdDataSetSql;
+
+import java.util.List;
+
+public class MdDataSetSqlVo extends MdDataSetSql {
+    private List<MdDataSetParam> paramList;
+
+    public List<MdDataSetParam> getParamList() {
+        return paramList;
+    }
+
+    public void setParamList(List<MdDataSetParam> paramList) {
+        this.paramList = paramList;
+    }
+
+    public MdDataSetSqlVo() {
+    }
+}

+ 37 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/vo/PtServiceRunLogVo.java

@@ -0,0 +1,37 @@
+package com.ruoyi.interfaces.domain.vo;
+
+import com.ruoyi.common.utils.JsonUtils;
+import com.ruoyi.interfaces.domain.PtService;
+import com.ruoyi.interfaces.domain.PtServiceRunLog;
+
+public class PtServiceRunLogVo extends PtServiceRunLog {
+    private Object paramList;
+
+    public PtServiceRunLogVo(PtService ptService) {
+        super(ptService);
+    }
+
+    public PtServiceRunLogVo(PtServiceRunLog serviceRunLog) {
+        super();
+        setLogId(serviceRunLog.getLogId());
+        setSerId(serviceRunLog.getSerId());
+        setMdId(serviceRunLog.getMdId());
+        setRunTm(serviceRunLog.getRunTm());
+        setExecTm(serviceRunLog.getExecTm());
+        setReturnData(serviceRunLog.getReturnData());
+        this.paramList = JsonUtils.jsonToPojo(serviceRunLog.getSenParam(), Object.class);
+    }
+
+    public PtServiceRunLogVo() {
+    }
+
+    public Object getParamList() {
+        return paramList;
+    }
+
+
+    public void setParamList(Object paramList) {
+        this.paramList = paramList;
+    }
+
+}

+ 65 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/mapper/PtServiceRunLogMapper.java

@@ -0,0 +1,65 @@
+package com.ruoyi.interfaces.mapper;
+
+import java.util.List;
+
+import com.ruoyi.common.annotation.DataSource;
+import com.ruoyi.common.enums.DataSourceType;
+import com.ruoyi.interfaces.domain.PtServiceRunLog;
+
+/**
+ * 服务运行logMapper接口
+ * 
+ * @author 朱得糠
+ * @date 2025-09-23
+ */
+@DataSource(DataSourceType.SLAVE)
+public interface PtServiceRunLogMapper 
+{
+    /**
+     * 查询服务运行log
+     * 
+     * @param logId 服务运行log主键
+     * @return 服务运行log
+     */
+    public PtServiceRunLog selectPtServiceRunLogByLogId(Long logId);
+
+    /**
+     * 查询服务运行log列表
+     * 
+     * @param ptServiceRunLog 服务运行log
+     * @return 服务运行log集合
+     */
+    public List<PtServiceRunLog> selectPtServiceRunLogList(PtServiceRunLog ptServiceRunLog);
+
+    /**
+     * 新增服务运行log
+     * 
+     * @param ptServiceRunLog 服务运行log
+     * @return 结果
+     */
+    public int insertPtServiceRunLog(PtServiceRunLog ptServiceRunLog);
+
+    /**
+     * 修改服务运行log
+     * 
+     * @param ptServiceRunLog 服务运行log
+     * @return 结果
+     */
+    public int updatePtServiceRunLog(PtServiceRunLog ptServiceRunLog);
+
+    /**
+     * 删除服务运行log
+     * 
+     * @param logId 服务运行log主键
+     * @return 结果
+     */
+    public int deletePtServiceRunLogByLogId(Long logId);
+
+    /**
+     * 批量删除服务运行log
+     * 
+     * @param logIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deletePtServiceRunLogByLogIds(Long[] logIds);
+}

+ 4 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IMdDataSetFileService.java

@@ -1,5 +1,6 @@
 package com.ruoyi.interfaces.service;
 
+import java.util.HashMap;
 import java.util.List;
 import com.ruoyi.interfaces.domain.MdDataSetFile;
 
@@ -60,4 +61,7 @@ public interface IMdDataSetFileService
     public int deleteMdDataSetFileById(Long id);
 
     int deleteMdDataSetFileByDcCode(String dcCode);
+
+    List<HashMap<String,Object>> queryFileData( MdDataSetFile mdDataSetFile) throws Exception;
+
 }

+ 61 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IPtServiceRunLogService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.interfaces.service;
+
+import java.util.List;
+import com.ruoyi.interfaces.domain.PtServiceRunLog;
+
+/**
+ * 服务运行logService接口
+ * 
+ * @author 朱得糠
+ * @date 2025-09-23
+ */
+public interface IPtServiceRunLogService 
+{
+    /**
+     * 查询服务运行log
+     * 
+     * @param logId 服务运行log主键
+     * @return 服务运行log
+     */
+    public PtServiceRunLog selectPtServiceRunLogByLogId(Long logId);
+
+    /**
+     * 查询服务运行log列表
+     * 
+     * @param ptServiceRunLog 服务运行log
+     * @return 服务运行log集合
+     */
+    public List<PtServiceRunLog> selectPtServiceRunLogList(PtServiceRunLog ptServiceRunLog);
+
+    /**
+     * 新增服务运行log
+     * 
+     * @param ptServiceRunLog 服务运行log
+     * @return 结果
+     */
+    public int insertPtServiceRunLog(PtServiceRunLog ptServiceRunLog);
+
+    /**
+     * 修改服务运行log
+     * 
+     * @param ptServiceRunLog 服务运行log
+     * @return 结果
+     */
+    public int updatePtServiceRunLog(PtServiceRunLog ptServiceRunLog);
+
+    /**
+     * 批量删除服务运行log
+     * 
+     * @param logIds 需要删除的服务运行log主键集合
+     * @return 结果
+     */
+    public int deletePtServiceRunLogByLogIds(Long[] logIds);
+
+    /**
+     * 删除服务运行log信息
+     * 
+     * @param logId 服务运行log主键
+     * @return 结果
+     */
+    public int deletePtServiceRunLogByLogId(Long logId);
+}

+ 3 - 2
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/MdAppFlowServiceImpl.java

@@ -6,6 +6,7 @@ import java.util.Map;
 
 import com.agentsflex.core.chain.Chain;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.interfaces.tinyflow.TinyflowUtil;
 import com.ruoyi.interfaces.tinyflow.parser.PrintNodeParser;
 import dev.tinyflow.core.Tinyflow;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -103,8 +104,8 @@ public class MdAppFlowServiceImpl implements IMdAppFlowService
     @Override
     public Map<String, Object> runFlow(MdAppFlow appFlow) {
         String flowGraph = appFlow.getFlowGraph();
-        Tinyflow tinyflow = new Tinyflow(flowGraph);
-        tinyflow.getChainParser().addNodeParser("printNode",new PrintNodeParser());
+        Tinyflow tinyflow = TinyflowUtil.getTinyflow(flowGraph);
+        //tinyflow.getChainParser().addNodeParser("printNode",new PrintNodeParser());
         Chain chain = tinyflow.toChain();
 
 

+ 29 - 21
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/MdDataSetFileServiceImpl.java

@@ -1,6 +1,13 @@
 package com.ruoyi.interfaces.service.impl;
 
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+
+import com.ruoyi.common.utils.ExcelParserUtil;
+import com.ruoyi.common.utils.file.FileUtils;
+import com.ruoyi.common.utils.poi.ExcelUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.interfaces.mapper.MdDataSetFileMapper;
@@ -9,85 +16,78 @@ import com.ruoyi.interfaces.service.IMdDataSetFileService;
 
 /**
  * 文件数据集Service业务层处理
- * 
+ *
  * @author 朱得糠
  * @date 2025-09-02
  */
 @Service
-public class MdDataSetFileServiceImpl implements IMdDataSetFileService 
-{
+public class MdDataSetFileServiceImpl implements IMdDataSetFileService {
     @Autowired
     private MdDataSetFileMapper mdDataSetFileMapper;
 
     /**
      * 查询文件数据集
-     * 
+     *
      * @param id 文件数据集主键
      * @return 文件数据集
      */
     @Override
-    public MdDataSetFile selectMdDataSetFileByDcCode(String id)
-    {
+    public MdDataSetFile selectMdDataSetFileByDcCode(String id) {
         return mdDataSetFileMapper.selectMdDataSetFileByDcCode(id);
     }
 
     /**
      * 查询文件数据集列表
-     * 
+     *
      * @param mdDataSetFile 文件数据集
      * @return 文件数据集
      */
     @Override
-    public List<MdDataSetFile> selectMdDataSetFileList(MdDataSetFile mdDataSetFile)
-    {
+    public List<MdDataSetFile> selectMdDataSetFileList(MdDataSetFile mdDataSetFile) {
         return mdDataSetFileMapper.selectMdDataSetFileList(mdDataSetFile);
     }
 
     /**
      * 新增文件数据集
-     * 
+     *
      * @param mdDataSetFile 文件数据集
      * @return 结果
      */
     @Override
-    public int insertMdDataSetFile(MdDataSetFile mdDataSetFile)
-    {
+    public int insertMdDataSetFile(MdDataSetFile mdDataSetFile) {
         return mdDataSetFileMapper.insertMdDataSetFile(mdDataSetFile);
     }
 
     /**
      * 修改文件数据集
-     * 
+     *
      * @param mdDataSetFile 文件数据集
      * @return 结果
      */
     @Override
-    public int updateMdDataSetFile(MdDataSetFile mdDataSetFile)
-    {
+    public int updateMdDataSetFile(MdDataSetFile mdDataSetFile) {
         return mdDataSetFileMapper.updateMdDataSetFile(mdDataSetFile);
     }
 
     /**
      * 批量删除文件数据集
-     * 
+     *
      * @param ids 需要删除的文件数据集主键
      * @return 结果
      */
     @Override
-    public int deleteMdDataSetFileByIds(Long[] ids)
-    {
+    public int deleteMdDataSetFileByIds(Long[] ids) {
         return mdDataSetFileMapper.deleteMdDataSetFileByIds(ids);
     }
 
     /**
      * 删除文件数据集信息
-     * 
+     *
      * @param id 文件数据集主键
      * @return 结果
      */
     @Override
-    public int deleteMdDataSetFileById(Long id)
-    {
+    public int deleteMdDataSetFileById(Long id) {
         return mdDataSetFileMapper.deleteMdDataSetFileById(id);
     }
 
@@ -96,4 +96,12 @@ public class MdDataSetFileServiceImpl implements IMdDataSetFileService
 
         return mdDataSetFileMapper.deleteMdDataSetFileByDcCode(dcCode);
     }
+
+    @Override
+    public List<HashMap<String, Object>> queryFileData(MdDataSetFile mdDataSetFile) throws Exception {
+        String profilePath = FileUtils.getProfilePath(mdDataSetFile.getFilePath());
+        File file = new File(profilePath);
+        ExcelParserUtil.parseExcel(file);
+        return Collections.emptyList();
+    }
 }

+ 93 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/PtServiceRunLogServiceImpl.java

@@ -0,0 +1,93 @@
+package com.ruoyi.interfaces.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.interfaces.mapper.PtServiceRunLogMapper;
+import com.ruoyi.interfaces.domain.PtServiceRunLog;
+import com.ruoyi.interfaces.service.IPtServiceRunLogService;
+
+/**
+ * 服务运行logService业务层处理
+ * 
+ * @author 朱得糠
+ * @date 2025-09-23
+ */
+@Service
+public class PtServiceRunLogServiceImpl implements IPtServiceRunLogService 
+{
+    @Autowired
+    private PtServiceRunLogMapper ptServiceRunLogMapper;
+
+    /**
+     * 查询服务运行log
+     * 
+     * @param logId 服务运行log主键
+     * @return 服务运行log
+     */
+    @Override
+    public PtServiceRunLog selectPtServiceRunLogByLogId(Long logId)
+    {
+        return ptServiceRunLogMapper.selectPtServiceRunLogByLogId(logId);
+    }
+
+    /**
+     * 查询服务运行log列表
+     * 
+     * @param ptServiceRunLog 服务运行log
+     * @return 服务运行log
+     */
+    @Override
+    public List<PtServiceRunLog> selectPtServiceRunLogList(PtServiceRunLog ptServiceRunLog)
+    {
+        return ptServiceRunLogMapper.selectPtServiceRunLogList(ptServiceRunLog);
+    }
+
+    /**
+     * 新增服务运行log
+     * 
+     * @param ptServiceRunLog 服务运行log
+     * @return 结果
+     */
+    @Override
+    public int insertPtServiceRunLog(PtServiceRunLog ptServiceRunLog)
+    {
+        return ptServiceRunLogMapper.insertPtServiceRunLog(ptServiceRunLog);
+    }
+
+    /**
+     * 修改服务运行log
+     * 
+     * @param ptServiceRunLog 服务运行log
+     * @return 结果
+     */
+    @Override
+    public int updatePtServiceRunLog(PtServiceRunLog ptServiceRunLog)
+    {
+        return ptServiceRunLogMapper.updatePtServiceRunLog(ptServiceRunLog);
+    }
+
+    /**
+     * 批量删除服务运行log
+     * 
+     * @param logIds 需要删除的服务运行log主键
+     * @return 结果
+     */
+    @Override
+    public int deletePtServiceRunLogByLogIds(Long[] logIds)
+    {
+        return ptServiceRunLogMapper.deletePtServiceRunLogByLogIds(logIds);
+    }
+
+    /**
+     * 删除服务运行log信息
+     * 
+     * @param logId 服务运行log主键
+     * @return 结果
+     */
+    @Override
+    public int deletePtServiceRunLogByLogId(Long logId)
+    {
+        return ptServiceRunLogMapper.deletePtServiceRunLogByLogId(logId);
+    }
+}

+ 2 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/TinyflowUtil.java

@@ -1,6 +1,7 @@
 package com.ruoyi.interfaces.tinyflow;
 
 import com.ruoyi.interfaces.tinyflow.parser.PrintNodeParser;
+import com.ruoyi.interfaces.tinyflow.parser.SQLNodeParser;
 import com.ruoyi.interfaces.tinyflow.parser.ServiceNodeParser;
 import dev.tinyflow.core.Tinyflow;
 
@@ -9,6 +10,7 @@ public class TinyflowUtil {
         Tinyflow tinyflow = new Tinyflow(data);
         tinyflow.getChainParser().addNodeParser("printNode",new PrintNodeParser());
         tinyflow.getChainParser().addNodeParser("serviceNode",new ServiceNodeParser());
+        tinyflow.getChainParser().addNodeParser("SQLNodeParser",new SQLNodeParser());
         return tinyflow;
     }
 }

+ 1 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/node/PrintNode.java

@@ -97,6 +97,7 @@ public class PrintNode extends BaseNode {
         data.add(dataMap);
         data.add(dataMap2);
         data.add(dataMap3);
+
         result.put("msg",input);
         result.put("data",data);
 

+ 38 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/node/SQLNode.java

@@ -0,0 +1,38 @@
+package com.ruoyi.interfaces.tinyflow.node;
+
+import com.agentsflex.core.chain.Chain;
+import com.agentsflex.core.chain.node.BaseNode;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.interfaces.database.DynamicDataSourceManager;
+import com.ruoyi.interfaces.domain.vo.MdDataSetSqlVo;
+import com.ruoyi.interfaces.mapper.SysMetaDatasourceMapper;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SQLNode  extends BaseNode {
+
+    private MdDataSetSqlVo  mdDataSetSqlVo;
+
+    public MdDataSetSqlVo getMdDataSetSqlVo() {
+        return mdDataSetSqlVo;
+    }
+
+    public void setMdDataSetSqlVo(MdDataSetSqlVo mdDataSetSqlVo) {
+        this.mdDataSetSqlVo = mdDataSetSqlVo;
+    }
+
+    @Override
+    protected Map<String, Object> execute(Chain chain) {
+        Map<String,Object> map = new HashMap<>();
+
+        Map<String, Object> parameterValues = chain.getParameterValues(this); //获取参数
+
+        SysMetaDatasourceMapper mapper = SpringUtils.getBean(SysMetaDatasourceMapper.class);
+        DynamicDataSourceManager dynamic = SpringUtils.getBean(DynamicDataSourceManager.class);
+
+
+        return Collections.emptyMap();
+    }
+}

+ 2 - 4
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/node/ServiceNode.java

@@ -49,7 +49,7 @@ public class ServiceNode extends BaseNode {
                     }
                 }
                 try {
-                     map.put("result",JsonUtils.jsonToPojo(HttpUtils.sendBodyPost(ptService.getUrl(), paramMap, headers), Map.class));
+                     map.putAll(JsonUtils.jsonToPojo(HttpUtils.sendBodyPost(ptService.getUrl(), paramMap, headers), Map.class));
                 } catch (IOException e) {
                     throw new RuntimeException(e);
                 }
@@ -62,15 +62,13 @@ public class ServiceNode extends BaseNode {
                         paramString += (serviceParam.getParamCode() + "=" + paramValue) + "&";
                     }
                 }
-                map.put("result",JsonUtils.jsonToPojo(HttpUtils.sendGet(ptService.getUrl(), paramString, headers), Map.class));
+                map.putAll(JsonUtils.jsonToPojo(HttpUtils.sendGet(ptService.getUrl(), paramString, headers), Map.class));
                 break;
         }
-
         /**
          * 调用服务
          */
 
-
         return map;
     }
 }

+ 24 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/tinyflow/parser/SQLNodeParser.java

@@ -0,0 +1,24 @@
+package com.ruoyi.interfaces.tinyflow.parser;
+
+import com.agentsflex.core.chain.node.BaseNode;
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.interfaces.domain.PtService;
+import com.ruoyi.interfaces.domain.vo.MdDataSetSqlVo;
+import com.ruoyi.interfaces.tinyflow.node.SQLNode;
+import com.ruoyi.interfaces.tinyflow.node.ServiceNode;
+import dev.tinyflow.core.Tinyflow;
+import dev.tinyflow.core.parser.BaseNodeParser;
+
+public class SQLNodeParser  extends BaseNodeParser {
+    @Override
+    protected BaseNode doParse(JSONObject root, JSONObject data, Tinyflow tinyflow) {
+        SQLNode sqlNode = new SQLNode();
+        if (data != null) {
+            sqlNode.setId(data.getString("id"));
+            sqlNode.setName(data.getString("name"));
+            sqlNode.setDescription(data.getString("description"));
+            sqlNode.setMdDataSetSqlVo(data.getObject("mdDataSetSqlVo", MdDataSetSqlVo.class));
+        }
+        return sqlNode;
+    }
+}

+ 83 - 0
ruoyi-api-patform/src/main/resources/mapper/interfaces/PtServiceRunLogMapper.xml

@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.interfaces.mapper.PtServiceRunLogMapper">
+
+    <resultMap type="com.ruoyi.interfaces.domain.PtServiceRunLog" id="PtServiceRunLogResult">
+        <result property="logId"    column="log_id"    />
+        <result property="serId"    column="ser_id"    />
+        <result property="mdId"    column="md_id"    />
+        <result property="runTm"    column="run_tm"    />
+        <result property="senParam"    column="sen_param"    />
+        <result property="returnData"    column="return_data"    />
+        <result property="execTm"    column="exec_tm"    />
+    </resultMap>
+
+    <sql id="selectPtServiceRunLogVo">
+        select log_id, ser_id, md_id, run_tm, sen_param, return_data, exec_tm from pt_service_run_log
+    </sql>
+
+    <select id="selectPtServiceRunLogList" parameterType="com.ruoyi.interfaces.domain.PtServiceRunLog" resultMap="PtServiceRunLogResult">
+        <include refid="selectPtServiceRunLogVo"/>
+        <where>
+            <if test="logId != null "> and log_id = #{logId}</if>
+            <if test="serId != null  and serId != ''"> and ser_id = #{serId}</if>
+            <if test="mdId != null  and mdId != ''"> and md_id = #{mdId}</if>
+            <if test="runTm != null "> and run_tm = #{runTm}</if>
+            <if test="senParam != null  and senParam != ''"> and sen_param = #{senParam}</if>
+            <if test="returnData != null  and returnData != ''"> and return_data = #{returnData}</if>
+            <if test="execTm != null "> and exec_tm = #{execTm}</if>
+        </where>
+        order by run_tm desc
+    </select>
+
+    <select id="selectPtServiceRunLogByLogId" parameterType="Long" resultMap="PtServiceRunLogResult">
+        <include refid="selectPtServiceRunLogVo"/>
+        where log_id = #{logId}
+    </select>
+
+    <insert id="insertPtServiceRunLog" parameterType="com.ruoyi.interfaces.domain.PtServiceRunLog" useGeneratedKeys="true" keyProperty="logId">
+        insert into pt_service_run_log
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="serId != null and serId != ''">ser_id,</if>
+            <if test="mdId != null">md_id,</if>
+            <if test="runTm != null">run_tm,</if>
+            <if test="senParam != null">sen_param,</if>
+            <if test="returnData != null">return_data,</if>
+            <if test="execTm != null">exec_tm,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="serId != null and serId != ''">#{serId},</if>
+            <if test="mdId != null">#{mdId},</if>
+            <if test="runTm != null">#{runTm},</if>
+            <if test="senParam != null">#{senParam},</if>
+            <if test="returnData != null">#{returnData},</if>
+            <if test="execTm != null">#{execTm},</if>
+        </trim>
+    </insert>
+
+    <update id="updatePtServiceRunLog" parameterType="com.ruoyi.interfaces.domain.PtServiceRunLog">
+        update pt_service_run_log
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="serId != null and serId != ''">ser_id = #{serId},</if>
+            <if test="mdId != null">md_id = #{mdId},</if>
+            <if test="runTm != null">run_tm = #{runTm},</if>
+            <if test="senParam != null">sen_param = #{senParam},</if>
+            <if test="returnData != null">return_data = #{returnData},</if>
+            <if test="execTm != null">exec_tm = #{execTm},</if>
+        </trim>
+        where log_id = #{logId}
+    </update>
+
+    <delete id="deletePtServiceRunLogByLogId" parameterType="Long">
+        delete from pt_service_run_log where log_id = #{logId}
+    </delete>
+
+    <delete id="deletePtServiceRunLogByLogIds" parameterType="String">
+        delete from pt_service_run_log where log_id in
+        <foreach item="logId" collection="array" open="(" separator="," close=")">
+            #{logId}
+        </foreach>
+    </delete>
+</mapper>

+ 166 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/ExcelParserUtil.java

@@ -0,0 +1,166 @@
+package com.ruoyi.common.utils;
+
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.*;
+
+/**
+ * Excel解析工具类
+ * 提供静态方法将Excel数据解析为List<Map>结构
+ * 第一列作为Map的key,其他列作为value
+ */
+public class ExcelParserUtil {
+
+    /**
+     * 解析Excel文件数据
+     * @param file Excel文件对象
+     * @return List<Map>结构的数据,第一列作为Map的key
+     * @throws Exception 如果文件格式不支持或解析过程中出现错误
+     */
+    public static List<Map<String, String>> parseExcel(File file) throws Exception {
+        List<Map<String, String>> resultList = new ArrayList<>();
+        FileInputStream fis = new FileInputStream(file);
+        Workbook workbook;
+        
+        // 根据文件扩展名创建不同的Workbook实例
+        String fileName = file.getName().toLowerCase();
+        if (fileName.endsWith(".xlsx")) {
+            workbook = new XSSFWorkbook(fis);
+        } else if (fileName.endsWith(".xls")) {
+            workbook = new HSSFWorkbook(fis);
+        } else {
+            fis.close();
+            throw new IllegalArgumentException("不支持的文件格式,仅支持.xls和.xlsx格式");
+        }
+        
+        try {
+            // 获取第一个工作表
+            Sheet sheet = workbook.getSheetAt(0);
+            
+            // 获取第一行作为字段名
+            Row headerRow = sheet.getRow(0);
+            if (headerRow == null) {
+                throw new RuntimeException("Excel文件没有数据");
+            }
+            
+            // 读取字段名(第一列)
+            String keyName = getCellValue(headerRow.getCell(0));
+            if (keyName == null || keyName.trim().isEmpty()) {
+                throw new RuntimeException("第一列第一行必须包含字段名");
+            }
+            
+            // 读取数据行
+            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
+                Row row = sheet.getRow(i);
+                if (row == null) continue;
+                
+                // 获取key值(第一列的值)
+                Cell keyCell = row.getCell(0);
+                if (keyCell == null) continue;
+                
+                String keyValue = getCellValue(keyCell);
+                if (keyValue == null || keyValue.trim().isEmpty()) continue;
+                
+                // 创建Map存储这一行的数据
+                Map<String, String> rowMap = new LinkedHashMap<>();
+                rowMap.put(keyName, keyValue);
+                
+                // 读取其他列的数据
+                for (int j = 1; j < headerRow.getLastCellNum(); j++) {
+                    Cell headerCell = headerRow.getCell(j);
+                    if (headerCell == null) continue;
+                    
+                    String columnName = getCellValue(headerCell);
+                    if (columnName == null || columnName.trim().isEmpty()) continue;
+                    
+                    Cell dataCell = row.getCell(j);
+                    String cellValue = dataCell != null ? getCellValue(dataCell) : "";
+                    rowMap.put(columnName, cellValue);
+                }
+                
+                resultList.add(rowMap);
+            }
+        } finally {
+            // 确保资源被关闭
+            workbook.close();
+            fis.close();
+        }
+        
+        return resultList;
+    }
+
+    /**
+     * 获取单元格的值
+     * @param cell 单元格对象
+     * @return 单元格的字符串表示
+     */
+    private static String getCellValue(Cell cell) {
+        if (cell == null) {
+            return "";
+        }
+        
+        switch (cell.getCellType()) {
+            case STRING:
+                return cell.getStringCellValue().trim();
+            case NUMERIC:
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    return cell.getDateCellValue().toString();
+                } else {
+                    // 避免显示为科学计数法
+                    double num = cell.getNumericCellValue();
+                    if (num == (long) num) {
+                        return String.valueOf((long) num);
+                    } else {
+                        return String.valueOf(num);
+                    }
+                }
+            case BOOLEAN:
+                return String.valueOf(cell.getBooleanCellValue());
+            case FORMULA:
+                // 尝试计算公式结果
+                try {
+                    FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
+                    CellValue cellValue = evaluator.evaluate(cell);
+                    switch (cellValue.getCellType()) {
+                        case NUMERIC:
+                            return String.valueOf(cellValue.getNumberValue());
+                        case STRING:
+                            return cellValue.getStringValue();
+                        case BOOLEAN:
+                            return String.valueOf(cellValue.getBooleanValue());
+                        default:
+                            return cell.getCellFormula();
+                    }
+                } catch (Exception e) {
+                    return cell.getCellFormula();
+                }
+            default:
+                return "";
+        }
+    }
+
+    /**
+     * 测试方法
+     */
+    public static void main(String[] args) {
+        try {
+            // 替换为你的Excel文件路径
+            File excelFile = new File("D:\\工作\\运维导数据\\溧阳.xlsx");
+            
+            // 调用解析方法
+            List<Map<String, String>> result = parseExcel(excelFile);
+
+            String s = JsonUtils.objectToJson(result);
+
+            // 输出结果
+            System.out.println(s);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 56 - 88
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java

@@ -11,6 +11,7 @@ import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.ArrayUtils;
 import com.ruoyi.common.config.RuoYiConfig;
@@ -21,44 +22,35 @@ import org.apache.commons.io.FilenameUtils;
 
 /**
  * 文件处理工具类
- * 
+ *
  * @author ruoyi
  */
-public class FileUtils
-{
+public class FileUtils {
     public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
 
     /**
      * 输出指定文件的byte数组
-     * 
+     *
      * @param filePath 文件路径
-     * @param os 输出流
+     * @param os       输出流
      * @return
      */
-    public static void writeBytes(String filePath, OutputStream os) throws IOException
-    {
+    public static void writeBytes(String filePath, OutputStream os) throws IOException {
         FileInputStream fis = null;
-        try
-        {
+        try {
             File file = new File(filePath);
-            if (!file.exists())
-            {
+            if (!file.exists()) {
                 throw new FileNotFoundException(filePath);
             }
             fis = new FileInputStream(file);
             byte[] b = new byte[1024];
             int length;
-            while ((length = fis.read(b)) > 0)
-            {
+            while ((length = fis.read(b)) > 0) {
                 os.write(b, 0, length);
             }
-        }
-        catch (IOException e)
-        {
+        } catch (IOException e) {
             throw e;
-        }
-        finally
-        {
+        } finally {
             IOUtils.close(os);
             IOUtils.close(fis);
         }
@@ -71,33 +63,28 @@ public class FileUtils
      * @return 目标文件
      * @throws IOException IO异常
      */
-    public static String writeImportBytes(byte[] data) throws IOException
-    {
+    public static String writeImportBytes(byte[] data) throws IOException {
         return writeBytes(data, RuoYiConfig.getImportPath());
     }
 
     /**
      * 写数据到文件中
      *
-     * @param data 数据
+     * @param data      数据
      * @param uploadDir 目标文件
      * @return 目标文件
      * @throws IOException IO异常
      */
-    public static String writeBytes(byte[] data, String uploadDir) throws IOException
-    {
+    public static String writeBytes(byte[] data, String uploadDir) throws IOException {
         FileOutputStream fos = null;
         String pathName = "";
-        try
-        {
+        try {
             String extension = getFileExtendName(data);
             pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
             File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);
             fos = new FileOutputStream(file);
             fos.write(data);
-        }
-        finally
-        {
+        } finally {
             IOUtils.close(fos);
         }
         return FileUploadUtils.getPathFileName(uploadDir, pathName);
@@ -105,17 +92,15 @@ public class FileUtils
 
     /**
      * 删除文件
-     * 
+     *
      * @param filePath 文件
      * @return
      */
-    public static boolean deleteFile(String filePath)
-    {
+    public static boolean deleteFile(String filePath) {
         boolean flag = false;
         File file = new File(filePath);
         // 路径为文件且不为空则进行删除
-        if (file.isFile() && file.exists())
-        {
+        if (file.isFile() && file.exists()) {
             flag = file.delete();
         }
         return flag;
@@ -123,32 +108,28 @@ public class FileUtils
 
     /**
      * 文件名称验证
-     * 
+     *
      * @param filename 文件名称
      * @return true 正常 false 非法
      */
-    public static boolean isValidFilename(String filename)
-    {
+    public static boolean isValidFilename(String filename) {
         return filename.matches(FILENAME_PATTERN);
     }
 
     /**
      * 检查文件是否可下载
-     * 
+     *
      * @param resource 需要下载的文件
      * @return true 正常 false 非法
      */
-    public static boolean checkAllowDownload(String resource)
-    {
+    public static boolean checkAllowDownload(String resource) {
         // 禁止目录上跳级别
-        if (StringUtils.contains(resource, ".."))
-        {
+        if (StringUtils.contains(resource, "..")) {
             return false;
         }
 
         // 检查允许下载的文件规则
-        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
-        {
+        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) {
             return true;
         }
 
@@ -158,33 +139,25 @@ public class FileUtils
 
     /**
      * 下载文件名重新编码
-     * 
-     * @param request 请求对象
+     *
+     * @param request  请求对象
      * @param fileName 文件名
      * @return 编码后的文件名
      */
-    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
-    {
+    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException {
         final String agent = request.getHeader("USER-AGENT");
         String filename = fileName;
-        if (agent.contains("MSIE"))
-        {
+        if (agent.contains("MSIE")) {
             // IE浏览器
             filename = URLEncoder.encode(filename, "utf-8");
             filename = filename.replace("+", " ");
-        }
-        else if (agent.contains("Firefox"))
-        {
+        } else if (agent.contains("Firefox")) {
             // 火狐浏览器
             filename = new String(fileName.getBytes(), "ISO8859-1");
-        }
-        else if (agent.contains("Chrome"))
-        {
+        } else if (agent.contains("Chrome")) {
             // google浏览器
             filename = URLEncoder.encode(filename, "utf-8");
-        }
-        else
-        {
+        } else {
             // 其它浏览器
             filename = URLEncoder.encode(filename, "utf-8");
         }
@@ -194,11 +167,10 @@ public class FileUtils
     /**
      * 下载文件名重新编码
      *
-     * @param response 响应对象
+     * @param response     响应对象
      * @param realFileName 真实文件名
      */
-    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
-    {
+    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException {
         String percentEncodedFileName = percentEncode(realFileName);
 
         StringBuilder contentDispositionValue = new StringBuilder();
@@ -220,36 +192,27 @@ public class FileUtils
      * @param s 需要百分号编码的字符串
      * @return 百分号编码后的字符串
      */
-    public static String percentEncode(String s) throws UnsupportedEncodingException
-    {
+    public static String percentEncode(String s) throws UnsupportedEncodingException {
         String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
         return encode.replaceAll("\\+", "%20");
     }
 
     /**
      * 获取图像后缀
-     * 
+     *
      * @param photoByte 图像数据
      * @return 后缀名
      */
-    public static String getFileExtendName(byte[] photoByte)
-    {
+    public static String getFileExtendName(byte[] photoByte) {
         String strFileExtendName = "jpg";
         if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
-                && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
-        {
+                && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) {
             strFileExtendName = "gif";
-        }
-        else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
-        {
+        } else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) {
             strFileExtendName = "jpg";
-        }
-        else if ((photoByte[0] == 66) && (photoByte[1] == 77))
-        {
+        } else if ((photoByte[0] == 66) && (photoByte[1] == 77)) {
             strFileExtendName = "bmp";
-        }
-        else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
-        {
+        } else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) {
             strFileExtendName = "png";
         }
         return strFileExtendName;
@@ -257,14 +220,12 @@ public class FileUtils
 
     /**
      * 获取文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi.png
-     * 
+     *
      * @param fileName 路径名称
      * @return 没有文件路径的名称
      */
-    public static String getName(String fileName)
-    {
-        if (fileName == null)
-        {
+    public static String getName(String fileName) {
+        if (fileName == null) {
             return null;
         }
         int lastUnixPos = fileName.lastIndexOf('/');
@@ -275,17 +236,24 @@ public class FileUtils
 
     /**
      * 获取不带后缀文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi
-     * 
+     *
      * @param fileName 路径名称
      * @return 没有文件路径和后缀的名称
      */
-    public static String getNameNotSuffix(String fileName)
-    {
-        if (fileName == null)
-        {
+    public static String getNameNotSuffix(String fileName) {
+        if (fileName == null) {
             return null;
         }
         String baseName = FilenameUtils.getBaseName(fileName);
         return baseName;
     }
+
+    /**
+     * 获取上传文件的绝对文件路径
+     * @param filePath
+     * @return
+     */
+    public static String getProfilePath(String filePath) {
+        return RuoYiConfig.getProfile() + filePath.replace("/profile", "");
+    }
 }