liujie
2026-04-17 8afcc37e0de5aa3ca3cc3f175f180e9339f60424
update
9个文件已修改
207 ■■■■■ 已修改文件
admin-server/src/main/java/com/estate/expert/admin/component/fuzzy/FuzzyApiComponent.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-server/src/main/java/com/estate/expert/admin/domain/exam/record/RecordRepository.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-server/src/main/java/com/estate/expert/admin/domain/exam/task/check/CheckTaskRepository.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-server/src/main/java/com/estate/expert/admin/service/impl/ReportServiceImpl.java 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-server/src/main/java/com/estate/expert/admin/stat/report/data/DeviceReportData.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-server/src/main/java/com/estate/expert/admin/stat/report/data/SystemReportData.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-server/src/main/resources/application-test-aliyun.yml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-server/src/main/resources/application-xll-aliyun.yml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-server/src/main/resources/application.yml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-server/src/main/java/com/estate/expert/admin/component/fuzzy/FuzzyApiComponent.java
@@ -45,9 +45,10 @@
     * 模糊评估API的远程服务地址
     * 
     */
    // private static final String FUZZY_EVALUATION_API_URL = "http://47.93.28.249:8081/api/Fuzzy_evaluation";
//     private static final String FUZZY_EVALUATION_API_URL = "http://47.93.28.249:8081/api/Fuzzy_evaluation";
    @Value("${fuzzy.api.url}")
    private static final String FUZZY_EVALUATION_API_URL = "http://192.168.110.188:8081/api/Fuzzy_evaluation";
    private static final String FUZZY_EVALUATION_API_URL = "http://localhost:5000/api/Fuzzy_evaluation";
    /**
     * HTTP客户端模板
admin-server/src/main/java/com/estate/expert/admin/domain/exam/record/RecordRepository.java
@@ -26,4 +26,12 @@
            "and r.check_task_id in (:taskIds) " +
            "group by r.device_id, r.problem_id", nativeQuery = true)
    List<Object[]> countDeviceChecksByTaskIds(@Param("taskIds") List<Integer> taskIds);
    @Query(value = "select r.device_id, count(distinct r.check_task_id) " +
            "from record r " +
            "where r.deleted = false " +
            "and r.device_id is not null " +
            "and r.check_task_id in (:taskIds) " +
            "group by r.device_id", nativeQuery = true)
    List<Object[]> countDeviceCheckTasksByTaskIds(@Param("taskIds") List<Integer> taskIds);
}
admin-server/src/main/java/com/estate/expert/admin/domain/exam/task/check/CheckTaskRepository.java
@@ -66,4 +66,41 @@
            "and t.plan.state = :planState")
    List<Integer> listTaskIdsByProjectAndPlanState(@Param("projectId") Integer projectId,
                                                   @Param("planState") PlanState planState);
    @Query("select t.id from CheckTask t " +
            "where t.deleted = false " +
            "and t.project.id = :projectId " +
            "and t.project.client.id = :clientId " +
            "and t.plan.deleted = false " +
            "and t.plan.state = :planState")
    List<Integer> listTaskIdsByProjectAndClientAndPlanState(@Param("projectId") Integer projectId,
                                                             @Param("clientId") Integer clientId,
                                                             @Param("planState") PlanState planState);
    @Query("select t.id from CheckTask t " +
            "where t.deleted = false " +
            "and t.project.id = :projectId " +
            "and t.project.client.id = :clientId " +
            "and t.plan.deleted = false")
    List<Integer> listTaskIdsByProjectAndClient(@Param("projectId") Integer projectId,
                                                 @Param("clientId") Integer clientId);
    @Query("select t from CheckTask t " +
            "where t.deleted = false " +
            "and t.project.id = :projectId " +
            "and t.project.client.id = :clientId " +
            "and t.plan.deleted = false " +
            "and t.plan.state = :planState")
    List<CheckTask> listByProjectAndClientAndPlanState(@Param("projectId") Integer projectId,
                                                        @Param("clientId") Integer clientId,
                                                        @Param("planState") PlanState planState);
    @Query("select t from CheckTask t " +
            "where t.deleted = false " +
            "and t.project.id = :projectId " +
            "and t.project.client.id = :clientId " +
            "and t.plan.deleted = false " +
            "and t.state >= 3")
    List<CheckTask> listClosedByProjectAndClient(@Param("projectId") Integer projectId,
                                                  @Param("clientId") Integer clientId);
}
admin-server/src/main/java/com/estate/expert/admin/service/impl/ReportServiceImpl.java
@@ -5,9 +5,8 @@
import com.estate.expert.admin.domain.business.device.usage.DeviceUsage;
import com.estate.expert.admin.domain.exam.eval.fuzzy.EvalFuzzyResult;
import com.estate.expert.admin.domain.exam.eval.score.EvalScoreResult;
import com.estate.expert.admin.domain.exam.record.error.ErrorRecord;
import com.estate.expert.admin.domain.exam.record.error.ErrorRecordRepository;
import com.estate.expert.admin.domain.exam.record.RecordRepository;
import com.estate.expert.admin.domain.exam.task.check.CheckTask;
import com.estate.expert.admin.domain.exam.task.check.CheckTaskRepository;
import com.estate.expert.admin.domain.report.ReportTemplate;
import com.estate.expert.admin.domain.plan.PlanState;
@@ -34,9 +33,11 @@
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
 * 报告数据服务实现类
@@ -65,9 +66,6 @@
    @Resource
    private ErrorRecordRepository errorRecordRepository;
    @Resource
    private RecordRepository recordRepository;
    @Resource
    private CheckTaskRepository checkTaskRepository;
@@ -208,6 +206,7 @@
        var hierarchy = evalFuzzyResult.getPlan().getSystemScoreExpert().getModel().getHierarchy().getContent();
        var problemFrequency = buildSystemProblemFrequency(project.getId(), records);
        var projectCheckCount = countProjectChecks(project.getId());
        // 生成报告数据
        return SystemFuzzyReportData.builder()
@@ -221,7 +220,7 @@
                .devices(devices)
                .records(records)
                .problemHazardCounts(problemFrequency.problemHazardCounts())
                .problemCheckCounts(problemFrequency.problemCheckCounts())
                .projectCheckCount(projectCheckCount)
                .build()
                .generate();
    }
@@ -237,6 +236,7 @@
        var hierarchy = evalFuzzyResult.getPlan().getSystemScoreExpert().getModel().getHierarchy().getContent();
        var problemFrequency = buildSystemProblemFrequency(project.getId(), records);
        var projectCheckCount = countProjectChecks(project.getId());
        // 生成报告数据
        return SystemScoreReportData.builder()
@@ -250,20 +250,20 @@
                .devices(devices)
                .records(records)
                .problemHazardCounts(problemFrequency.problemHazardCounts())
                .problemCheckCounts(problemFrequency.problemCheckCounts())
                .projectCheckCount(projectCheckCount)
                .build()
                .generate();
    }
    private record ProblemFrequency(Map<Integer, Long> problemHazardCounts, Map<Integer, Long> problemCheckCounts) {
    private record ProblemFrequency(Map<Integer, Long> problemHazardCounts) {
    }
    private record DeviceProblemFrequency(Map<String, Long> problemHazardCounts, Map<String, Long> problemCheckCounts) {
    private record DeviceProblemFrequency(Map<String, Long> problemHazardCounts, Map<Integer, Long> deviceCheckCounts) {
    }
    private ProblemFrequency buildSystemProblemFrequency(Integer projectId, List<com.estate.expert.admin.domain.exam.record.error.ErrorRecord> currentTaskRecords) {
        if (projectId == null || currentTaskRecords == null || currentTaskRecords.isEmpty()) {
            return new ProblemFrequency(Collections.emptyMap(), Collections.emptyMap());
            return new ProblemFrequency(Collections.emptyMap());
        }
        var problemIds = currentTaskRecords.stream()
@@ -272,12 +272,12 @@
                .distinct()
                .toList();
        if (problemIds.isEmpty()) {
            return new ProblemFrequency(Collections.emptyMap(), Collections.emptyMap());
            return new ProblemFrequency(Collections.emptyMap());
        }
        var taskIds = checkTaskRepository.listTaskIdsByProjectAndPlanState(projectId, PlanState.COMPLETE);
        if (taskIds == null || taskIds.isEmpty()) {
            return new ProblemFrequency(Collections.emptyMap(), Collections.emptyMap());
            return new ProblemFrequency(Collections.emptyMap());
        }
        Map<Integer, Long> hazardCounts = new HashMap<>();
@@ -288,41 +288,26 @@
            hazardCounts.put(((Number) row[0]).intValue(), ((Number) row[1]).longValue());
        }
        Map<Integer, Long> checkCounts = new HashMap<>();
        for (var row : recordRepository.countSystemChecksByTaskIdsAndProblemIds(taskIds, problemIds)) {
            if (row == null || row.length < 2 || row[0] == null || row[1] == null) {
                continue;
            }
            checkCounts.put(((Number) row[0]).intValue(), ((Number) row[1]).longValue());
        }
        return new ProblemFrequency(hazardCounts, checkCounts);
        return new ProblemFrequency(hazardCounts);
    }
    private DeviceProblemFrequency buildDeviceProblemFrequency(Integer projectId) {
        if (projectId == null) {
            return new DeviceProblemFrequency(Collections.emptyMap(), Collections.emptyMap());
        }
        var taskIds = checkTaskRepository.listTaskIdsByProjectAndPlanState(projectId, PlanState.COMPLETE);
        if (taskIds == null || taskIds.isEmpty()) {
    private DeviceProblemFrequency buildDeviceProblemFrequency(Integer projectId, Integer clientId) {
        var taskIds = listTaskIdsByProjectAndClient(projectId, clientId);
        if (taskIds.isEmpty()) {
            return new DeviceProblemFrequency(Collections.emptyMap(), Collections.emptyMap());
        }
        Map<String, Long> hazardCounts = new HashMap<>();
        for (var row : errorRecordRepository.countDeviceHazardsByTaskIds(taskIds)) {
            collectDeviceFrequency(row, hazardCounts);
            collectDeviceProblemFrequency(row, hazardCounts);
        }
        Map<String, Long> checkCounts = new HashMap<>();
        for (var row : recordRepository.countDeviceChecksByTaskIds(taskIds)) {
            collectDeviceFrequency(row, checkCounts);
        }
        Map<Integer, Long> deviceCheckCounts = buildDeviceCheckFrequencyByCompletedTasks(projectId, clientId);
        return new DeviceProblemFrequency(hazardCounts, checkCounts);
        return new DeviceProblemFrequency(hazardCounts, deviceCheckCounts);
    }
    private void collectDeviceFrequency(Object[] row, Map<String, Long> target) {
    private void collectDeviceProblemFrequency(Object[] row, Map<String, Long> target) {
        if (row == null || row.length < 3 || row[0] == null || row[2] == null) {
            return;
        }
@@ -330,6 +315,45 @@
        Integer problemId = row[1] == null ? null : ((Number) row[1]).intValue();
        Long count = ((Number) row[2]).longValue();
        target.put(DeviceReportData.buildDeviceProblemKey(deviceId, problemId), count);
    }
    private Map<Integer, Long> buildDeviceCheckFrequencyByCompletedTasks(Integer projectId, Integer clientId) {
        if (projectId == null || clientId == null) {
            return Collections.emptyMap();
        }
        var tasks = checkTaskRepository.listClosedByProjectAndClient(projectId, clientId);
        if (tasks == null || tasks.isEmpty()) {
            return Collections.emptyMap();
        }
        Map<Integer, Long> deviceCheckCounts = new HashMap<>();
        for (CheckTask task : tasks) {
            for (Integer deviceId : collectTaskCheckedDeviceIds(task)) {
                deviceCheckCounts.merge(deviceId, 1L, Long::sum);
            }
        }
        return deviceCheckCounts;
    }
    private Set<Integer> collectTaskCheckedDeviceIds(CheckTask task) {
        Set<Integer> deviceIds = new HashSet<>();
        if (task == null) {
            return deviceIds;
        }
        addDeviceIds(task.getDeviceFuzzyMap(), deviceIds);
        addDeviceIds(task.getDeviceScoreMap(), deviceIds);
        return deviceIds;
    }
    private void addDeviceIds(Map<Integer, Float> deviceMap, Set<Integer> target) {
        if (deviceMap == null || deviceMap.isEmpty()) {
            return;
        }
        for (Integer deviceId : deviceMap.keySet()) {
            if (deviceId == null) {
                continue;
            }
            target.add(deviceId);
        }
    }
    private JSONObject buildFuzzyDeviceReportData(EvalFuzzyResult evalFuzzyResult, EvalScoreResult scoreResult,  ReportTemplate reportTemplate) {
@@ -340,7 +364,8 @@
        var deviceIds = evalFuzzyResult.getDeviceResMap().keySet();
        var devices = deviceService.findAllById(deviceIds);
        var hierarchy = evalFuzzyResult.getPlan().getDeviceScoreExpert().getModel().getHierarchy().getContent();
        var problemFrequency = buildDeviceProblemFrequency(project.getId());
        var clientId = project.getClient() != null ? project.getClient().getId() : null;
        var problemFrequency = buildDeviceProblemFrequency(project.getId(), clientId);
        // 生成报告数据
        return DeviceFuzzyReportData.builder()
@@ -353,7 +378,7 @@
                .devices(devices)
                .records(records)
                .deviceProblemHazardCounts(problemFrequency.problemHazardCounts())
                .deviceProblemCheckCounts(problemFrequency.problemCheckCounts())
                .deviceCheckCounts(problemFrequency.deviceCheckCounts())
                .build()
                .generate();
    }
@@ -366,7 +391,8 @@
        var deviceIds = evalFuzzyResult.getDeviceResMap().keySet();
        var devices = deviceService.findAllById(deviceIds);
        var hierarchy = evalFuzzyResult.getPlan().getDeviceScoreExpert().getModel().getHierarchy().getContent();
        var problemFrequency = buildDeviceProblemFrequency(project.getId());
        var clientId = project.getClient() != null ? project.getClient().getId() : null;
        var problemFrequency = buildDeviceProblemFrequency(project.getId(), clientId);
        // 生成报告数据
        return DeviceScoreReportData.builder()
@@ -380,11 +406,31 @@
                .devices(devices)
                .records(records)
                .deviceProblemHazardCounts(problemFrequency.problemHazardCounts())
                .deviceProblemCheckCounts(problemFrequency.problemCheckCounts())
                .deviceCheckCounts(problemFrequency.deviceCheckCounts())
                .build()
                .generate();
    }
    private List<Integer> listTaskIdsByProjectAndClient(Integer projectId, Integer clientId) {
        if (projectId == null || clientId == null) {
            return Collections.emptyList();
        }
        var taskIds = checkTaskRepository.listTaskIdsByProjectAndClient(projectId, clientId);
        if (taskIds == null) {
            return Collections.emptyList();
        }
        return taskIds;
    }
    private long countProjectChecks(Integer projectId) {
        if (projectId == null) {
            return 0L;
        }
        var taskIds = checkTaskRepository.listTaskIdsByProjectAndPlanState(projectId, PlanState.COMPLETE);
        if (taskIds == null) {
            return 0L;
        }
        return taskIds.size();
    }
}
admin-server/src/main/java/com/estate/expert/admin/stat/report/data/DeviceReportData.java
@@ -34,7 +34,7 @@
    Map<String, Long> deviceProblemHazardCounts;
    Map<String, Long> deviceProblemCheckCounts;
    Map<Integer, Long> deviceCheckCounts;
    /**
     * 生成报告数据
@@ -264,10 +264,11 @@
    }
    private long getDeviceProblemCheckCount(ErrorRecord record) {
        if (deviceProblemCheckCounts == null) {
        Integer deviceId = record != null && record.getDevice() != null ? record.getDevice().getId() : null;
        if (deviceId == null || deviceCheckCounts == null) {
            return 0L;
        }
        return deviceProblemCheckCounts.getOrDefault(buildDeviceProblemKey(record), 0L);
        return Math.max(deviceCheckCounts.getOrDefault(deviceId, 0L), 0L);
    }
    private String buildDeviceProblemKey(ErrorRecord record) {
admin-server/src/main/java/com/estate/expert/admin/stat/report/data/SystemReportData.java
@@ -37,7 +37,7 @@
    Map<Integer, Long> problemHazardCounts;
    Map<Integer, Long> problemCheckCounts;
    long projectCheckCount;
    // 评估结果
    @Override
@@ -221,11 +221,7 @@
    }
    private long getProblemCheckCount(ErrorRecord record) {
        var problemId = record != null && record.getProblem() != null ? record.getProblem().getId() : null;
        if (problemId == null || problemCheckCounts == null) {
            return 0L;
        }
        return problemCheckCounts.getOrDefault(problemId, 0L);
        return Math.max(projectCheckCount, 0L);
    }
    /**
admin-server/src/main/resources/application-test-aliyun.yml
@@ -1,5 +1,5 @@
server:
  port: 8181
  port: 8182
spring:
  profiles:
@@ -25,9 +25,9 @@
      max-request-size: 100MB
  datasource:
    url: jdbc:mysql://localhost:3306/estate?useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/estate_new?useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull
    username: admin
    password: ZXtzbsMuCIFbmBW4HtOjRd
    driver-class-name: com.mysql.jdbc.Driver
    hikari:
      auto-commit: true
@@ -45,7 +45,7 @@
file:
  upload:
    dir: /data/uploads
    dir: /data/upload
license:
admin-server/src/main/resources/application-xll-aliyun.yml
@@ -25,7 +25,7 @@
      max-request-size: 100MB
  datasource:
    url: jdbc:mysql://localhost:3306/estate?useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
    url: jdbc:mysql://localhost:3306/estate_new?useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
    username: admin
    password: ZXtzbsMuCIFbmBW4HtOjRd
    driver-class-name: com.mysql.jdbc.Driver
@@ -46,7 +46,7 @@
# 上传文件目录
file:
  upload:
    dir: /data/uploads
    dir: /data/upload
# 高德地图API密钥
map:
admin-server/src/main/resources/application.yml
@@ -25,7 +25,7 @@
      max-request-size: 100MB
  datasource:
    url: jdbc:mysql://localhost:3306/estate_dgzp?useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
    url: jdbc:mysql://localhost:3306/estate_new?useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
    username: admin
    password: ZXtzbsMuCIFbmBW4HtOjRd
    driver-class-name: com.mysql.jdbc.Driver
@@ -46,7 +46,7 @@
# 上传文件目录
file:
  upload:
    dir: /data/uploads
    dir: /data/upload
# 高德地图API密钥
map: