Parcourir la source

审核bug修复

ZhuDeKang il y a 3 mois
Parent
commit
8d6fd7a259
17 fichiers modifiés avec 454 ajouts et 223 suppressions
  1. 0 23
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdDataSetController.java
  2. 2 1
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdDataSetFileController.java
  3. 6 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdDataSetSqlController.java
  4. 3 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/PtServiceController.java
  5. 10 1
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/MdDataSetParam.java
  6. 0 1
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/PtService.java
  7. 22 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/vo/MdDataSetFileVo.java
  8. 2 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/mapper/MdDataSetFileMapper.java
  9. 2 1
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IMdDataSetFileService.java
  10. 4 1
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IMdDataSetSqlService.java
  11. 2 3
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/MdAppFlowServiceImpl.java
  12. 6 4
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/MdDataSetFileServiceImpl.java
  13. 63 21
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/MdDataSetSqlServiceImpl.java
  14. 317 0
      ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/utils/ExcelParser.java
  15. 14 0
      ruoyi-api-patform/src/main/resources/mapper/interfaces/PtServiceMapper.xml
  16. 0 166
      ruoyi-common/src/main/java/com/ruoyi/common/utils/ExcelParserUtil.java
  17. 1 1
      ruoyi-framework/src/main/java/com/ruoyi/framework/websocket/WebSocketServer.java

+ 0 - 23
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdDataSetController.java

@@ -103,29 +103,6 @@ public class MdDataSetController extends BaseController {
         return toAjax(mdDataSetService.deleteMdDataSetByDsCodes(dsCodes));
     }
 
-    @Autowired
-    private IMdDataSetApiService setApiService;
-    @Autowired
-    private IMdDataSetFileService setFileService;
-    @Autowired
-    private IMdDataSetSqlService setSqlService;
-
-    @GetMapping("/getSetConfig")
-    public AjaxResult getSetConfig(MdDataSet dataSet) {
-
-        if (StringUtils.isNull(dataSet.getDcCode())) return error("数据集不可为空");
-        if (StringUtils.isNull(dataSet.getDcType())) return error("请配置数据集类型");
-        switch (dataSet.getDcType()) {
-            case "sql":
-                return success(setSqlService.selectMdDataSetSqlByDcCode(dataSet.getDcCode()));
-            case "api":
-                return success(setApiService.selectMdDataSetApiByDcCode(dataSet.getDcCode()));
-            case "file":
-                return success(setFileService.selectMdDataSetFileByDcCode(dataSet.getDcCode()));
-        }
-
-        return error("数据集类型异常");
-    }
 
 }
 

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

@@ -4,6 +4,7 @@ import java.util.HashMap;
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 
+import com.ruoyi.interfaces.domain.vo.MdDataSetFileVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -86,7 +87,7 @@ public class MdDataSetFileController extends BaseController {
     }
 
     @PostMapping("/query")
-    public AjaxResult query(@RequestBody MdDataSetFile mdDataSetFile) {
+    public AjaxResult query(@RequestBody MdDataSetFileVo mdDataSetFile) {
         try {
             List<HashMap<String, Object>> hashMaps = mdDataSetFileService.queryFileData(mdDataSetFile);
             return AjaxResult.success(hashMaps);

+ 6 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdDataSetSqlController.java

@@ -3,6 +3,7 @@ package com.ruoyi.interfaces.controller;
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 
+import com.ruoyi.interfaces.domain.vo.MdDataSetSqlVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -94,4 +95,9 @@ public class MdDataSetSqlController extends BaseController
     {
         return toAjax(mdDataSetSqlService.deleteMdDataSetSqlByIds(ids));
     }
+    @PostMapping("/runSql")
+    public AjaxResult runSql(@RequestBody MdDataSetSqlVo mdDataSetSql){
+        return AjaxResult.success(mdDataSetSqlService.runSql(mdDataSetSql));
+    }
+
 }

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

@@ -216,6 +216,9 @@ public class PtServiceController extends BaseController {
     @GetMapping("/audit")
     public AjaxResult audit(PtService service) {
         Date nowDate = DateUtils.getNowDate();
+        if (StringUtils.isEmpty(service.getSrvId())){
+            return error("服务id不可为空");
+        }
         MdAudit srv = new MdAudit(null, service.getSrvId(), "AUDIT", service.getAudit(), getUsername(), nowDate, service.getAuditRemark());
         int i = mdAuditService.insertMdAudit(srv);
         service.setAuditBy(getUsername());

+ 10 - 1
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/MdDataSetParam.java

@@ -42,8 +42,17 @@ public class MdDataSetParam extends BaseEntity
     /** 排序 */
     @Excel(name = "排序")
     private Integer sort;
+    private String symbol;
 
-    public void setDcCode(String dcCode) 
+    public String getSymbol() {
+        return symbol;
+    }
+
+    public void setSymbol(String symbol) {
+        this.symbol = symbol;
+    }
+
+    public void setDcCode(String dcCode)
     {
         this.dcCode = dcCode;
     }

+ 0 - 1
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/PtService.java

@@ -125,7 +125,6 @@ public class PtService implements Serializable {
      * 审核状态 0=待审核;1=已审核;2 = 驳回
      */
     private String audit;
-    @TableField(exist = false)
     private String auditBy;
     private String auditRemark;
     private Date auditTime;

+ 22 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/vo/MdDataSetFileVo.java

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

+ 2 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/mapper/MdDataSetFileMapper.java

@@ -5,6 +5,7 @@ import java.util.List;
 import com.ruoyi.common.annotation.DataSource;
 import com.ruoyi.common.enums.DataSourceType;
 import com.ruoyi.interfaces.domain.MdDataSetFile;
+import org.apache.ibatis.annotations.Mapper;
 
 /**
  * 文件数据集Mapper接口
@@ -13,6 +14,7 @@ import com.ruoyi.interfaces.domain.MdDataSetFile;
  * @date 2025-09-02
  */
 @DataSource(DataSourceType.SLAVE)
+@Mapper
 public interface MdDataSetFileMapper 
 {
     /**

+ 2 - 1
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IMdDataSetFileService.java

@@ -3,6 +3,7 @@ package com.ruoyi.interfaces.service;
 import java.util.HashMap;
 import java.util.List;
 import com.ruoyi.interfaces.domain.MdDataSetFile;
+import com.ruoyi.interfaces.domain.vo.MdDataSetFileVo;
 
 /**
  * 文件数据集Service接口
@@ -62,6 +63,6 @@ public interface IMdDataSetFileService
 
     int deleteMdDataSetFileByDcCode(String dcCode);
 
-    List<HashMap<String,Object>> queryFileData( MdDataSetFile mdDataSetFile) throws Exception;
+    List<HashMap<String,Object>> queryFileData( MdDataSetFileVo mdDataSetFile) throws Exception;
 
 }

+ 4 - 1
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IMdDataSetSqlService.java

@@ -1,7 +1,10 @@
 package com.ruoyi.interfaces.service;
 
 import java.util.List;
+import java.util.Map;
+
 import com.ruoyi.interfaces.domain.MdDataSetSql;
+import com.ruoyi.interfaces.domain.vo.MdDataSetSqlVo;
 
 /**
  * sql数据集Service接口
@@ -60,5 +63,5 @@ public interface IMdDataSetSqlService
     public int deleteMdDataSetSqlById(Long id);
 
     int deleteMdDataSetSqlByDcCode(String dcCode);
-
+    public List<Map<String, Object>> runSql(MdDataSetSqlVo mdDataSetSql);
 }

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

@@ -134,6 +134,7 @@ public class MdAppFlowServiceImpl implements IMdAppFlowService {
                         nodeMap.put("id", completedNode.getId());
                         nodeMap.put("name", completedNode.getName());
                         nodeMap.put("nodeState", "START");
+                        nodeMap.put("timestamp", System.currentTimeMillis());
                         WebSocketUsers.sendMessageToUserByText(session, JsonUtils.objectToJson(nodeMap));
                     }
                 }
@@ -147,6 +148,7 @@ public class MdAppFlowServiceImpl implements IMdAppFlowService {
                         nodeMap.put("name", completedNode.getName());
                         nodeMap.put("result", executeResult);
                         nodeMap.put("nodeState", "END");
+                        nodeMap.put("timestamp", System.currentTimeMillis());
                         WebSocketUsers.sendMessageToUserByText(session, JsonUtils.objectToJson(nodeMap));
                     }
                 }
@@ -181,9 +183,6 @@ public class MdAppFlowServiceImpl implements IMdAppFlowService {
                         nodeMap.put("errorType", "UNKNOWN_ERROR");
                         nodeMap.put("errorMessage", error.getMessage());
                     }
-
-
-
                     WebSocketUsers.sendMessageToUserByText(session, JsonUtils.objectToJson(nodeMap));
                 }
             }

+ 6 - 4
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/MdDataSetFileServiceImpl.java

@@ -5,9 +5,10 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 
-import com.ruoyi.common.utils.ExcelParserUtil;
+import com.ruoyi.interfaces.utils.ExcelParser;
 import com.ruoyi.common.utils.file.FileUtils;
-import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.interfaces.domain.MdDataSetParam;
+import com.ruoyi.interfaces.domain.vo.MdDataSetFileVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.interfaces.mapper.MdDataSetFileMapper;
@@ -98,10 +99,11 @@ public class MdDataSetFileServiceImpl implements IMdDataSetFileService {
     }
 
     @Override
-    public List<HashMap<String, Object>> queryFileData(MdDataSetFile mdDataSetFile) throws Exception {
+    public List<HashMap<String, Object>> queryFileData(MdDataSetFileVo mdDataSetFile) throws Exception {
         String profilePath = FileUtils.getProfilePath(mdDataSetFile.getFilePath());
         File file = new File(profilePath);
-        ExcelParserUtil.parseExcel(file);
+        List<MdDataSetParam> paramList = mdDataSetFile.getParamList();
+        ExcelParser.parseExcelWithParams(file, paramList);
         return Collections.emptyList();
     }
 }

+ 63 - 21
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/MdDataSetSqlServiceImpl.java

@@ -1,93 +1,98 @@
 package com.ruoyi.interfaces.service.impl;
 
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+
+import com.ruoyi.interfaces.database.DynamicDataSourceManager;
+import com.ruoyi.interfaces.domain.MdDataSetParam;
+import com.ruoyi.interfaces.domain.SysMetaDatasource;
+import com.ruoyi.interfaces.domain.vo.MdDataSetSqlVo;
+import com.ruoyi.interfaces.mapper.SysMetaDatasourceMapper;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import com.ruoyi.interfaces.mapper.MdDataSetSqlMapper;
 import com.ruoyi.interfaces.domain.MdDataSetSql;
 import com.ruoyi.interfaces.service.IMdDataSetSqlService;
 
+import javax.sql.DataSource;
+
 /**
  * sql数据集Service业务层处理
- * 
+ *
  * @author 朱得糠
  * @date 2025-09-02
  */
 @Service
-public class MdDataSetSqlServiceImpl implements IMdDataSetSqlService 
-{
+public class MdDataSetSqlServiceImpl implements IMdDataSetSqlService {
     @Autowired
     private MdDataSetSqlMapper mdDataSetSqlMapper;
 
     /**
      * 查询sql数据集
-     * 
+     *
      * @param id sql数据集主键
      * @return sql数据集
      */
     @Override
-    public MdDataSetSql selectMdDataSetSqlByDcCode(String id)
-    {
+    public MdDataSetSql selectMdDataSetSqlByDcCode(String id) {
         return mdDataSetSqlMapper.selectMdDataSetSqlByDcCode(id);
     }
 
     /**
      * 查询sql数据集列表
-     * 
+     *
      * @param mdDataSetSql sql数据集
      * @return sql数据集
      */
     @Override
-    public List<MdDataSetSql> selectMdDataSetSqlList(MdDataSetSql mdDataSetSql)
-    {
+    public List<MdDataSetSql> selectMdDataSetSqlList(MdDataSetSql mdDataSetSql) {
         return mdDataSetSqlMapper.selectMdDataSetSqlList(mdDataSetSql);
     }
 
     /**
      * 新增sql数据集
-     * 
+     *
      * @param mdDataSetSql sql数据集
      * @return 结果
      */
     @Override
-    public int insertMdDataSetSql(MdDataSetSql mdDataSetSql)
-    {
+    public int insertMdDataSetSql(MdDataSetSql mdDataSetSql) {
         return mdDataSetSqlMapper.insertMdDataSetSql(mdDataSetSql);
     }
 
     /**
      * 修改sql数据集
-     * 
+     *
      * @param mdDataSetSql sql数据集
      * @return 结果
      */
     @Override
-    public int updateMdDataSetSql(MdDataSetSql mdDataSetSql)
-    {
+    public int updateMdDataSetSql(MdDataSetSql mdDataSetSql) {
         return mdDataSetSqlMapper.updateMdDataSetSql(mdDataSetSql);
     }
 
     /**
      * 批量删除sql数据集
-     * 
+     *
      * @param ids 需要删除的sql数据集主键
      * @return 结果
      */
     @Override
-    public int deleteMdDataSetSqlByIds(Long[] ids)
-    {
+    public int deleteMdDataSetSqlByIds(Long[] ids) {
         return mdDataSetSqlMapper.deleteMdDataSetSqlByIds(ids);
     }
 
     /**
      * 删除sql数据集信息
-     * 
+     *
      * @param id sql数据集主键
      * @return 结果
      */
     @Override
-    public int deleteMdDataSetSqlById(Long id)
-    {
+    public int deleteMdDataSetSqlById(Long id) {
         return mdDataSetSqlMapper.deleteMdDataSetSqlById(id);
     }
 
@@ -95,4 +100,41 @@ public class MdDataSetSqlServiceImpl implements IMdDataSetSqlService
     public int deleteMdDataSetSqlByDcCode(String dcCode) {
         return mdDataSetSqlMapper.deleteMdDataSetSqlByDcCode(dcCode);
     }
+
+    @Autowired
+    private SysMetaDatasourceMapper sysMetaDatasourceMapper;
+
+    @Autowired
+    private DynamicDataSourceManager dataSourceManager;
+
+
+    @Override
+    public List<Map<String, Object>> runSql(MdDataSetSqlVo mdDataSetSql) {
+        String runSql = mdDataSetSql.getRunSql();
+
+        List<MdDataSetParam> paramList = mdDataSetSql.getParamList();
+
+        for (MdDataSetParam mdDataSetParam : paramList) {
+            runSql = runSql.replace("#{" + mdDataSetParam.getParamCode() + "}", mdDataSetParam.getParamValue());
+        }
+        System.out.println("runSql:" + runSql);
+        SysMetaDatasource sysMetaDatasource = sysMetaDatasourceMapper.selectSysMetaDatasourceByDsCode(mdDataSetSql.getDsCode());
+
+        DataSource dataSource = dataSourceManager.getSysDataSource(sysMetaDatasource);
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+        return jdbcTemplate.query(runSql, (rs, rowNum) -> {
+            Map<String, Object> row = new HashMap<>();
+            int columnCount = rs.getMetaData().getColumnCount();
+
+            for (int i = 1; i <= columnCount; i++) {
+                String columnName = rs.getMetaData().getColumnName(i);
+                Object value = rs.getObject(i);
+                row.put(columnName, value);
+            }
+            return row;
+        });
+    }
+
+
 }

+ 317 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/utils/ExcelParser.java

@@ -0,0 +1,317 @@
+package com.ruoyi.interfaces.utils;
+
+import com.ruoyi.interfaces.domain.MdDataSetParam;
+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.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * 增强的Excel解析工具类 - 支持数据检索
+ */
+public class ExcelParser {
+
+    /**
+     * 根据参数配置解析Excel数据
+     *
+     * @param file   Excel文件
+     * @param params 查询参数配置列表
+     * @return 符合条件的数据列表
+     */
+    public static List<Map<String, String>> parseExcelWithParams(File file, List<MdDataSetParam> params) throws Exception {
+        Predicate<Map<String, String>> filter = buildFilterFromParams(params);
+        return parseExcel(file, filter);
+    }
+
+    /**
+     * 根据参数配置解析Excel数据(支持排序)
+     *
+     * @param file       Excel文件
+     * @param params     查询参数配置列表
+     * @param sortParams 排序参数
+     * @return 符合条件并排序的数据列表
+     */
+    public static List<Map<String, String>> parseExcelWithParams(File file,
+                                                                 List<MdDataSetParam> params,
+                                                                 List<MdDataSetParam> sortParams) throws Exception {
+        List<Map<String, String>> result = parseExcelWithParams(file, params);
+
+        if (sortParams != null && !sortParams.isEmpty()) {
+            result = sortData(result, sortParams);
+        }
+
+        return result;
+    }
+
+    /**
+     * 从参数配置构建过滤条件
+     */
+    private static Predicate<Map<String, String>> buildFilterFromParams(List<MdDataSetParam> params) {
+        if (params == null || params.isEmpty()) {
+            return record -> true; // 无参数时返回所有记录
+        }
+
+        Predicate<Map<String, String>> filter = record -> true;
+
+        for (MdDataSetParam param : params) {
+            if (param.getParamCode() == null || param.getSymbol() == null) {
+                continue;
+            }
+
+            Predicate<Map<String, String>> condition = buildSingleCondition(param);
+            filter = filter.and(condition);
+        }
+
+        return filter;
+    }
+
+    /**
+     * 构建单个查询条件
+     */
+    private static Predicate<Map<String, String>> buildSingleCondition(MdDataSetParam param) {
+        String columnName = param.getParamCode(); // 使用paramCode作为列名
+        String symbol = param.getSymbol();
+        String value = param.getParamValue();
+
+        return record -> {
+            String recordValue = record.get(columnName);
+            if (recordValue == null) {
+                return false;
+            }
+
+            switch (symbol) {
+                case "=":
+                    return recordValue.equals(value);
+                case "!=":
+                    return !recordValue.equals(value);
+                case ">":
+                    return compareNumeric(recordValue, value) > 0;
+                case ">=":
+                    return compareNumeric(recordValue, value) >= 0;
+                case "<":
+                    return compareNumeric(recordValue, value) < 0;
+                case "<=":
+                    return compareNumeric(recordValue, value) <= 0;
+                case "contains":
+                    return recordValue.contains(value);
+                case "startsWith":
+                    return recordValue.startsWith(value);
+                case "endsWith":
+                    return recordValue.endsWith(value);
+                case "in":
+                    return value != null && Arrays.asList(value.split(",")).contains(recordValue);
+                case "notIn":
+                    return value != null && !Arrays.asList(value.split(",")).contains(recordValue);
+                case "like":
+                    return likeMatch(recordValue, value);
+                default:
+                    return true; // 未知符号默认返回true
+            }
+        };
+    }
+
+    /**
+     * 数值比较
+     */
+    private static int compareNumeric(String value1, String value2) {
+        try {
+            double num1 = Double.parseDouble(value1);
+            double num2 = Double.parseDouble(value2);
+            return Double.compare(num1, num2);
+        } catch (NumberFormatException e) {
+            // 如果不能转换为数字,则按字符串比较
+            return value1.compareTo(value2);
+        }
+    }
+
+    /**
+     * SQL LIKE 模式匹配
+     */
+    private static boolean likeMatch(String text, String pattern) {
+        if (text == null || pattern == null) {
+            return false;
+        }
+
+        // 将SQL LIKE模式转换为正则表达式
+        String regex = pattern
+                .replace("%", ".*")
+                .replace("_", ".");
+
+        return text.matches(regex);
+    }
+
+    /**
+     * 数据排序
+     */
+    private static List<Map<String, String>> sortData(List<Map<String, String>> data, List<MdDataSetParam> sortParams) {
+        if (data == null || data.isEmpty() || sortParams == null) {
+            return data;
+        }
+
+        data.sort((map1, map2) -> {
+            for (MdDataSetParam sortParam : sortParams) {
+                String columnName = sortParam.getParamCode();
+                String sortOrder = sortParam.getParamValue(); // 使用paramValue存储排序方向:ASC/DESC
+
+                String value1 = map1.get(columnName);
+                String value2 = map2.get(columnName);
+
+                int comparison;
+
+                // 尝试数值比较
+                try {
+                    double num1 = Double.parseDouble(value1);
+                    double num2 = Double.parseDouble(value2);
+                    comparison = Double.compare(num1, num2);
+                } catch (NumberFormatException e) {
+                    // 数值比较失败,使用字符串比较
+                    comparison = value1.compareTo(value2);
+                }
+
+                // 如果是降序,反转比较结果
+                if ("DESC".equalsIgnoreCase(sortOrder)) {
+                    comparison = -comparison;
+                }
+
+                if (comparison != 0) {
+                    return comparison;
+                }
+            }
+            return 0;
+        });
+
+        return data;
+    }
+
+    /**
+     * 基础解析方法
+     */
+    private static List<Map<String, String>> parseExcel(File file, Predicate<Map<String, String>> filter) throws Exception {
+        List<Map<String, String>> allData = parseExcelData(file);
+
+        if (filter == null) {
+            return allData;
+        }
+
+        return allData.stream()
+                .filter(filter)
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Excel数据解析核心方法
+     */
+    private static List<Map<String, String>> parseExcelData(File file) throws Exception {
+        // 这里使用你之前提供的Excel解析逻辑
+        List<Map<String, String>> resultList = new ArrayList<>();
+        FileInputStream fis = new FileInputStream(file);
+        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文件没有数据");
+            }
+
+            // 读取所有列名
+            List<String> columnNames = new ArrayList<>();
+            for (int j = 0; j < headerRow.getLastCellNum(); j++) {
+                Cell headerCell = headerRow.getCell(j);
+                if (headerCell != null) {
+                    String columnName = getCellValue(headerCell);
+                    if (columnName != null && !columnName.trim().isEmpty()) {
+                        columnNames.add(columnName);
+                    }
+                }
+            }
+
+            // 读取数据行
+            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
+                Row row = sheet.getRow(i);
+                if (row == null) continue;
+
+                Map<String, String> rowMap = new LinkedHashMap<>();
+                boolean hasData = false;
+
+                for (int j = 0; j < columnNames.size(); j++) {
+                    String columnName = columnNames.get(j);
+                    Cell dataCell = j < row.getLastCellNum() ? row.getCell(j) : null;
+                    String cellValue = dataCell != null ? getCellValue(dataCell) : "";
+
+                    if (cellValue != null && !cellValue.trim().isEmpty()) {
+                        hasData = true;
+                    }
+
+                    rowMap.put(columnName, cellValue != null ? cellValue : "");
+                }
+
+                if (hasData) {
+                    resultList.add(rowMap);
+                }
+            }
+        } finally {
+            workbook.close();
+            fis.close();
+        }
+
+        return resultList;
+    }
+
+    private static String getCellValue(Cell cell) {
+        // 你之前提供的getCellValue方法实现
+        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 "";
+        }
+    }
+}

+ 14 - 0
ruoyi-api-patform/src/main/resources/mapper/interfaces/PtServiceMapper.xml

@@ -626,6 +626,13 @@ PUBLISH_TIME
         <result column="APPLY_NUM" property="applyNum" jdbcType="INTEGER"/>
         <result column="DATA_NUM" property="dataNum" jdbcType="INTEGER"/>
         <result column="TEST_RUN_NUM" property="testRunNum" jdbcType="INTEGER"/>
+        <result column="S_AUDIT" property="audit" jdbcType="VARCHAR"/>
+        <result column="S_AUDIT_BY" property="auditBy" jdbcType="VARCHAR"/>
+        <result column="S_AUDIT_TIME" property="auditTime"/>
+        <result column="S_AUDIT_REMARK" property="auditRemark" jdbcType="VARCHAR"/>
+        <result column="S_PUBLISH" property="publish" jdbcType="VARCHAR"/>
+        <result column="S_PUBLISH_BY" property="publishBy" jdbcType="VARCHAR"/>
+        <result column="S_PUBLISH_TIME" property="publishTime"/>
     </resultMap>
 
 
@@ -727,6 +734,13 @@ PUBLISH_TIME
         s.MAINTAIN_UNIT,
         s.MAINTAIN_CONTACER,
         s.VIEW_NUM,
+        s.AUDIT as S_AUDIT,
+        s.AUDIT_BY AS S_AUDIT_BY,
+        s.AUDIT_TIME AS S_AUDIT_TIME,
+        s.AUDIT_REMARK AS S_AUDIT_REMARK,
+        s.PUBLISH AS S_PUBLISH,
+        s.PUBLISH_BY AS S_PUBLISH_BY,
+        s.PUBLISH_TIME AS S_PUBLISH_TIME,
         r.TEST_RUN_NUM
         from md_model_info m left join pt_service s on m.mdid = s.MDID
         LEFT JOIN ( select ser_id,count(1) as TEST_RUN_NUM from pt_service_run_log group by ser_id ) r ON s.SRV_ID =

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

@@ -1,166 +0,0 @@
-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();
-        }
-    }
-}

+ 1 - 1
ruoyi-framework/src/main/java/com/ruoyi/framework/websocket/WebSocketServer.java

@@ -28,7 +28,7 @@ public class WebSocketServer
     /**
      * 默认最多允许同时在线人数100
      */
-    public static int socketMaxOnlineCount = 100;
+    public static int socketMaxOnlineCount = 200;
 
     private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);