liujie
2026-01-22 bb7ce2c17f6541c8b21fb63b5aa4221433f2f974
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ClientServiceImpl.java
@@ -12,12 +12,14 @@
import com.ruoyi.system.mapper.PlanMapper;
import com.ruoyi.system.mapper.ProjectMapper;
import com.ruoyi.system.mapper.RecordMapper;
import com.ruoyi.system.mapper.TaskMapper;
import com.ruoyi.system.model.Check;
import com.ruoyi.system.model.Client;
import com.ruoyi.system.model.DeviceUsage;
import com.ruoyi.system.model.Plan;
import com.ruoyi.system.model.Project;
import com.ruoyi.system.model.Record;
import com.ruoyi.system.model.Task;
import com.ruoyi.system.service.ClientService;
import com.ruoyi.system.service.ProjectCategoryCalculator;
import com.ruoyi.system.vo.*;
@@ -49,6 +51,7 @@
    private final ProjectMapper projectMapper;
    private final PlanMapper planMapper;
    private final CheckMapper checkMapper;
    private final TaskMapper taskMapper;
    private final DeviceUsageMapper deviceUsageMapper;
    private final RecordMapper recordMapper;
    private final ProjectCategoryCalculator projectCategoryCalculator;
@@ -88,7 +91,15 @@
        // 查询在建工程项目(usage_type 表示项目用途类型,假设 0 表示在建工程)
        LambdaQueryWrapper<Project> projectWrapper = new LambdaQueryWrapper<>();
        projectWrapper.eq(Project::getDeleted, false)
                .eq(Project::getUsageType, 0); // 在建工程
                .ne(Project::getType, 2) // 在建工程
                .and(wrapper -> wrapper
                    .eq(Project::getStatus, 1)  // 在建项目
                    .or(w -> w
                        .eq(Project::getStatus, 2)  // 已完成项目
                        .ge(Project::getSuccessTime, monthStart)  // 完成时间 >= 开始日期
                        .le(Project::getSuccessTime, monthEnd)    // 完成时间 <= 结束日期
                    )
                );
        if (clientId != null) {
            projectWrapper.eq(Project::getClientId, clientId);
        }
@@ -101,15 +112,36 @@
        vo.setHousingProjectCount((int) housingCount);
        vo.setMunicipalProjectCount((int) municipalCount);
        // 计算检查覆盖率
        // 计算检查覆盖率(仅当查询时间范围为当月时才计算)
        List<Integer> projectIds = projects.stream().map(Project::getId).collect(Collectors.toList());
        if (!projectIds.isEmpty()) {
            LambdaQueryWrapper<Check> checkWrapper = new LambdaQueryWrapper<>();
            checkWrapper.in(Check::getProjectId, projectIds);
            List<Check> checks = checkMapper.selectList(checkWrapper);
        if (!projectIds.isEmpty() && isCurrentMonth(monthStart, monthEnd)) {
            // 1. 先查询符合条件的 Task
            LambdaQueryWrapper<Task> taskWrapper = new LambdaQueryWrapper<>();
            taskWrapper.in(Task::getProjectId, projectIds)
                    .eq(Task::getDeleted, false);
            List<Task> tasks = taskMapper.selectList(taskWrapper);
            List<Integer> checkedProjectIds = checks.stream()
                    .map(Check::getProjectId)
            if (!tasks.isEmpty()) {
                // 2. 获取 Task ID 列表
                List<Integer> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
                // 3. 建立 Task ID 到 Project ID 的映射
                Map<Integer, Integer> taskToProjectMap = tasks.stream()
                        .collect(Collectors.toMap(Task::getId, Task::getProjectId));
                // 4. 查询 record 表中 record_type='error' 且 device_id 为 null 的记录(项目检查)
                LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
                recordWrapper.eq(Record::getRecordType, "error")
                        .isNull(Record::getDeviceId)
                        .in(Record::getCheckTaskId, taskIds)
                        .eq(Record::getDeleted, false);
                List<Record> projectRecords = recordMapper.selectList(recordWrapper);
                // 5. 通过 Task 映射获取有检查记录的项目 ID
                List<Integer> checkedProjectIds = projectRecords.stream()
                        .map(Record::getCheckTaskId)
                        .map(taskToProjectMap::get)
                        .filter(Objects::nonNull)
                    .distinct()
                    .toList();
@@ -140,12 +172,32 @@
            vo.setHousingInspectionCoverage(0);
            vo.setMunicipalInspectionCoverage(0);
        }
        } else {
            vo.setHousingInspectionCoverage(0);
            vo.setMunicipalInspectionCoverage(0);
        }
        // 2. 统计本月检查情况
        calculateMonthlyInspectionForOngoing(vo, projects, projectIds, monthStart, monthEnd);
        // 3. 统计大型机械设备数
        vo.setMachineryStatistics(calculateMachineryStatistics(projectIds));
        List<MachineryStatisticsVO> machineryStatistics = calculateMachineryStatistics(projectIds);
        vo.setMachineryStatistics(machineryStatistics);
        // 汇总计算设备总数统计
        int machineryTotal = machineryStatistics.stream()
                .mapToInt(MachineryStatisticsVO::getTotal)
                .sum();
        int inspectedMachineryTotal = machineryStatistics.stream()
                .mapToInt(MachineryStatisticsVO::getInspectedCount)
                .sum();
        int uninspectedMachineryTotal = machineryStatistics.stream()
                .mapToInt(MachineryStatisticsVO::getUninspectedCount)
                .sum();
        vo.setMachineryTotal(machineryTotal);
        vo.setInspectedMachineryTotal(inspectedMachineryTotal);
        vo.setUninspectedMachineryTotal(uninspectedMachineryTotal);
        // 4. 统计重大隐患数
        calculateHazardStatistics(vo, projectIds);
@@ -165,7 +217,15 @@
        // 查询固定资产项目(usage_type 表示项目用途类型,假设 1 表示固定资产)
        LambdaQueryWrapper<Project> projectWrapper = new LambdaQueryWrapper<>();
        projectWrapper.eq(Project::getDeleted, false)
                .eq(Project::getUsageType, 1); // 固定资产
                .eq(Project::getUsageType, 1) // 固定资产
                .and(wrapper -> wrapper
                    .eq(Project::getStatus, 1)  // 在建项目
                    .or(w -> w
                        .eq(Project::getStatus, 2)  // 已完成项目
                        .ge(Project::getSuccessTime, monthStart)  // 完成时间 >= 开始日期
                        .le(Project::getSuccessTime, monthEnd)    // 完成时间 <= 结束日期
                    )
                );
        if (clientId != null) {
            projectWrapper.eq(Project::getClientId, clientId);
        }
@@ -177,17 +237,41 @@
        // 计算检查覆盖率
        List<Integer> projectIds = projects.stream().map(Project::getId).collect(Collectors.toList());
        if (!projectIds.isEmpty()) {
            LambdaQueryWrapper<Check> checkWrapper = new LambdaQueryWrapper<>();
            checkWrapper.in(Check::getProjectId, projectIds);
            List<Check> checks = checkMapper.selectList(checkWrapper);
            // 1. 先查询符合条件的 Task
            LambdaQueryWrapper<Task> taskWrapper = new LambdaQueryWrapper<>();
            taskWrapper.in(Task::getProjectId, projectIds)
                    .eq(Task::getDeleted, false);
            List<Task> tasks = taskMapper.selectList(taskWrapper);
            long checkedProjectCount = checks.stream()
                    .map(Check::getProjectId)
            if (!tasks.isEmpty()) {
                // 2. 获取 Task ID 列表
                List<Integer> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
                // 3. 建立 Task ID 到 Project ID 的映射
                Map<Integer, Integer> taskToProjectMap = tasks.stream()
                        .collect(Collectors.toMap(Task::getId, Task::getProjectId));
                // 4. 查询 record 表中 record_type='error' 且 device_id 为 null 的记录(项目检查)
                LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
                recordWrapper.eq(Record::getRecordType, "error")
                        .isNull(Record::getDeviceId)
                        .in(Record::getCheckTaskId, taskIds)
                        .eq(Record::getDeleted, false);
                List<Record> projectRecords = recordMapper.selectList(recordWrapper);
                // 5. 通过 Task 映射获取有检查记录的项目 ID
                long checkedProjectCount = projectRecords.stream()
                        .map(Record::getCheckTaskId)
                        .map(taskToProjectMap::get)
                        .filter(Objects::nonNull)
                    .distinct()
                    .count();
            vo.setInspectionCoverage(
                    projects.size() > 0 ? (int) Math.round(checkedProjectCount * 100.0 / projects.size()) : 0
            );
            } else {
                vo.setInspectionCoverage(0);
            }
        } else {
            vo.setInspectionCoverage(0);
        }
@@ -219,15 +303,44 @@
            return;
        }
        // 查询本月有检查记录的项目
        LambdaQueryWrapper<Check> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.in(Check::getProjectId, projectIds)
                .ge(Check::getTime, monthStart)
                .le(Check::getTime, monthEnd);
        List<Check> monthlyChecks = checkMapper.selectList(checkWrapper);
        // 1. 先查询符合条件的 Task(本月的任务)
        LambdaQueryWrapper<Task> taskWrapper = new LambdaQueryWrapper<>();
        taskWrapper.in(Task::getProjectId, projectIds)
                .ge(Task::getDate, monthStart.toInstant().atZone(ZoneId.systemDefault()).toLocalDate())
                .le(Task::getDate, monthEnd.toInstant().atZone(ZoneId.systemDefault()).toLocalDate())
                .eq(Task::getDeleted, false);
        List<Task> monthlyTasks = taskMapper.selectList(taskWrapper);
        List<Integer> inspectedProjectIds = monthlyChecks.stream()
                .map(Check::getProjectId)
        if (monthlyTasks.isEmpty()) {
            vo.setInspectedCount(0);
            vo.setInspectedHousingCount(0);
            vo.setInspectedMunicipalCount(0);
            vo.setUninspectedCount(projects.size());
            vo.setUninspectedHousingCount(vo.getHousingProjectCount());
            vo.setUninspectedMunicipalCount(vo.getMunicipalProjectCount());
            return;
        }
        // 2. 获取 Task ID 列表
        List<Integer> taskIds = monthlyTasks.stream().map(Task::getId).collect(Collectors.toList());
        // 3. 建立 Task ID 到 Project ID 的映射
        Map<Integer, Integer> taskToProjectMap = monthlyTasks.stream()
                .collect(Collectors.toMap(Task::getId, Task::getProjectId));
        // 4. 查询本月有检查记录的项目(查询 record 表中 record_type='error' 且 device_id 为 null 的记录)
        LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
        recordWrapper.eq(Record::getRecordType, "error")
                .isNull(Record::getDeviceId)
                .in(Record::getCheckTaskId, taskIds)
                .eq(Record::getDeleted, false);
        List<Record> monthlyRecords = recordMapper.selectList(recordWrapper);
        // 5. 通过 Task 映射获取有检查记录的项目 ID
        List<Integer> inspectedProjectIds = monthlyRecords.stream()
                .map(Record::getCheckTaskId)
                .map(taskToProjectMap::get)
                .filter(Objects::nonNull)
                .distinct()
                .toList();
@@ -265,15 +378,40 @@
            return;
        }
        // 查询本月有检查记录的项目
        LambdaQueryWrapper<Check> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.in(Check::getProjectId, projectIds)
                .ge(Check::getTime, monthStart)
                .le(Check::getTime, monthEnd);
        List<Check> monthlyChecks = checkMapper.selectList(checkWrapper);
        // 1. 先查询符合条件的 Task(本月的任务)
        LambdaQueryWrapper<Task> taskWrapper = new LambdaQueryWrapper<>();
        taskWrapper.in(Task::getProjectId, projectIds)
                .ge(Task::getDate, monthStart.toInstant().atZone(ZoneId.systemDefault()).toLocalDate())
                .le(Task::getDate, monthEnd.toInstant().atZone(ZoneId.systemDefault()).toLocalDate())
                .eq(Task::getDeleted, false);
        List<Task> monthlyTasks = taskMapper.selectList(taskWrapper);
        long inspectedCount = monthlyChecks.stream()
                .map(Check::getProjectId)
        if (monthlyTasks.isEmpty()) {
            vo.setInspectedCount(0);
            vo.setUninspectedCount(projects.size());
            return;
        }
        // 2. 获取 Task ID 列表
        List<Integer> taskIds = monthlyTasks.stream().map(Task::getId).collect(Collectors.toList());
        // 3. 建立 Task ID 到 Project ID 的映射
        Map<Integer, Integer> taskToProjectMap = monthlyTasks.stream()
                .collect(Collectors.toMap(Task::getId, Task::getProjectId));
        // 4. 查询本月有检查记录的项目(查询 record 表中 record_type='error' 且 device_id 为 null 的记录)
        LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
        recordWrapper.eq(Record::getRecordType, "error")
                .isNull(Record::getDeviceId)
                .in(Record::getCheckTaskId, taskIds)
                .eq(Record::getDeleted, false);
        List<Record> monthlyRecords = recordMapper.selectList(recordWrapper);
        // 5. 通过 Task 映射获取有检查记录的项目 ID
        long inspectedCount = monthlyRecords.stream()
                .map(Record::getCheckTaskId)
                .map(taskToProjectMap::get)
                .filter(Objects::nonNull)
                .distinct()
                .count();
@@ -305,8 +443,10 @@
        Map<Integer, Boolean> deviceInspectionMap = new HashMap<>();
        if (!deviceIds.isEmpty()) {
            LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
            recordWrapper.eq(Record::getDeleted, false)
                    .in(Record::getDeviceId, deviceIds);
            recordWrapper.eq(Record::getRecordType, "error")
                    .isNotNull(Record::getDeviceId)
                    .in(Record::getDeviceId, deviceIds)
                    .eq(Record::getDeleted, false);
            List<Record> records = recordMapper.selectList(recordWrapper);
            Set<Integer> inspectedDeviceIds = records.stream()
@@ -349,10 +489,11 @@
        }
        // 查询检查任务
        LambdaQueryWrapper<Check> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.in(Check::getProjectId, projectIds);
        List<Check> checks = checkMapper.selectList(checkWrapper);
        List<Integer> checkTaskIds = checks.stream().map(Check::getId).collect(Collectors.toList());
        LambdaQueryWrapper<Task> taskWrapper = new LambdaQueryWrapper<>();
        taskWrapper.in(Task::getProjectId, projectIds)
                .eq(Task::getDeleted, false);
        List<Task> tasks = taskMapper.selectList(taskWrapper);
        List<Integer> checkTaskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
        if (checkTaskIds.isEmpty()) {
            vo.setMajorHazardTotal(0);
@@ -361,11 +502,11 @@
            return;
        }
        // 查询重大隐患记录(level 表示隐患等级,假设 3 表示重大隐患)
        // 查询重大隐患记录(level 表示隐患等级,0 表示重大隐患)
        LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
        recordWrapper.eq(Record::getDeleted, false)
                .in(Record::getCheckTaskId, checkTaskIds)
                .eq(Record::getLevel, 3); // 重大隐患等级
                .eq(Record::getLevel, 0); // 重大隐患等级
        List<Record> majorHazards = recordMapper.selectList(recordWrapper);
        vo.setMajorHazardTotal(majorHazards.size());
@@ -394,10 +535,11 @@
        }
        // 查询检查任务
        LambdaQueryWrapper<Check> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.in(Check::getProjectId, projectIds);
        List<Check> checks = checkMapper.selectList(checkWrapper);
        List<Integer> checkTaskIds = checks.stream().map(Check::getId).collect(Collectors.toList());
        LambdaQueryWrapper<Task> taskWrapper = new LambdaQueryWrapper<>();
        taskWrapper.in(Task::getProjectId, projectIds)
                .eq(Task::getDeleted, false);
        List<Task> tasks = taskMapper.selectList(taskWrapper);
        List<Integer> checkTaskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
        if (checkTaskIds.isEmpty()) {
            vo.setMajorHazardTotal(0);
@@ -406,11 +548,11 @@
            return;
        }
        // 查询重大隐患记录(level 表示隐患等级,假设 3 表示重大隐患)
        // 查询重大隐患记录(level 表示隐患等级,0 表示重大隐患)
        LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
        recordWrapper.eq(Record::getDeleted, false)
                .in(Record::getCheckTaskId, checkTaskIds)
                .eq(Record::getLevel, 3); // 重大隐患等级
                .eq(Record::getLevel, 0); // 重大隐患等级
        List<Record> majorHazards = recordMapper.selectList(recordWrapper);
        vo.setMajorHazardTotal(majorHazards.size());
@@ -513,4 +655,27 @@
        YearMonth currentMonth = YearMonth.now();
        return Date.from(currentMonth.atEndOfMonth().atTime(23, 59, 59).atZone(ZoneId.systemDefault()).toInstant());
    }
    /**
     * 判断给定的日期范围是否为当前月份
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 如果日期范围在当前月份内则返回 true,否则返回 false
     */
    private boolean isCurrentMonth(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return false;
        }
        YearMonth currentMonth = YearMonth.now();
        LocalDate start = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate end = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        YearMonth startMonth = YearMonth.from(start);
        YearMonth endMonth = YearMonth.from(end);
        // 判断开始和结束日期是否都在当前月份
        return startMonth.equals(currentMonth) && endMonth.equals(currentMonth);
    }
}