From 075daef140ea17638529e09ef95b7cb28ed66ae5 Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期四, 22 一月 2026 13:48:22 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProjectInfoServiceImpl.java |  227 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 227 insertions(+), 0 deletions(-)

diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProjectInfoServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProjectInfoServiceImpl.java
index a285864..e1db0fa 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProjectInfoServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProjectInfoServiceImpl.java
@@ -1,10 +1,38 @@
 package com.ruoyi.system.service.impl;
 
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson2.JSONArray;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.system.model.Project;
 import com.ruoyi.system.model.ProjectInfo;
 import com.ruoyi.system.mapper.ProjectInfoMapper;
+import com.ruoyi.system.model.Record;
+import com.ruoyi.system.query.ProjectDangerousTrendQuery;
+import com.ruoyi.system.query.ProjectHiddenDangerTrendListQuery;
+import com.ruoyi.system.service.ProjectCategoryCalculator;
 import com.ruoyi.system.service.ProjectInfoService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.system.service.ProjectService;
+import com.ruoyi.system.service.RecordService;
+import com.ruoyi.system.vo.ProjectDangerousTrendVo;
+import com.ruoyi.system.vo.ProjectHiddenDangerList;
+import com.ruoyi.system.vo.ProjectHiddenDangerNextList;
+import com.ruoyi.system.vo.ProjectHiddenDangerTrendVo;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.YearMonth;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalAdjusters;
+import java.util.*;
+
+import static java.util.stream.Collectors.groupingBy;
 
 /**
  * <p>
@@ -17,4 +45,203 @@
 @Service
 public class ProjectInfoServiceImpl extends ServiceImpl<ProjectInfoMapper, ProjectInfo> implements ProjectInfoService {
 
+
+    @Autowired
+    private ProjectCategoryCalculator projectCategoryCalculator;
+
+    @Autowired
+    private ProjectService projectService;
+
+    @Override
+    public List<ProjectHiddenDangerTrendVo> getProjectHiddenDangerTrend(Integer projectId) {
+        // 获取上月第一天的时间
+        LocalDate lastMonth = LocalDate.now().minusMonths(1).with(TemporalAdjusters.firstDayOfMonth());
+        List<Record> list = this.baseMapper.getProjectHiddenDangerTrend(projectId,lastMonth+" 00:00:00",LocalDate.now()+" 23:59:59");
+        for (Record record : list) {
+            String hierarchyNames = record.getHierarchyNames();
+            JSONArray jsonArray = JSONArray.parseArray(hierarchyNames);
+            if(record.getDeviceId()!=null){
+                // 取出倒数第3个
+                String name = jsonArray.getString(jsonArray.size()-3);
+
+                record.setHierarchyName( name);
+            }else {
+                // 取出倒数第4个
+                String name = jsonArray.getString(jsonArray.size()-4);
+
+                record.setHierarchyName( name);
+            }
+
+
+        }
+
+        LocalDate thisMonth = LocalDate.now().minusMonths(0).with(TemporalAdjusters.firstDayOfMonth());
+        Map<String, List<Record>> map = list.stream().collect(groupingBy(Record::getHierarchyName));
+        List<ProjectHiddenDangerTrendVo> resultList = map.entrySet().stream().map(entry -> {
+            ProjectHiddenDangerTrendVo vo = new ProjectHiddenDangerTrendVo();
+            vo.setName(entry.getKey());
+            List<Record> value = entry.getValue();
+            long count = value.stream().filter(record -> record.getCreateTime().isAfter(thisMonth.atStartOfDay())).count();
+            // 根据value集合中的createTime 选出本月的数据
+            vo.setThisMonth((int) count);
+            vo.setLastMonth(value.size()-(int) count);
+
+            int num = vo.getThisMonth() - vo.getLastMonth();
+            if (num != 0) {
+                if(vo.getLastMonth()>0){
+                    Double rate = BigDecimal.valueOf(num).divide(BigDecimal.valueOf(vo.getLastMonth()), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP).doubleValue();
+                    vo.setRate(rate);
+                }else {
+                    vo.setRate(100.00d);
+                }
+            }else {
+                vo.setRate(0.00d);
+            }
+            return vo;
+        }).toList();
+
+
+        return resultList;
+    }
+
+    @Override
+    public List<ProjectHiddenDangerList> getProjectHiddenDangerTrendList(ProjectHiddenDangerTrendListQuery query) {
+        List<Record> list = this.baseMapper.getProjectHiddenDangerTrend(query.getProjectId(),getMonthBoundaries(query.getStartTime(),true)+" 00:00:00",getMonthBoundaries(query.getEndTime(),false)+" 23:59:59");
+        for (Record record : list) {
+            String hierarchyNames = record.getHierarchyNames();
+            JSONArray jsonArray = JSONArray.parseArray(hierarchyNames);
+            if(record.getDeviceId()!=null){
+                // 取出倒数第3个
+                String name = jsonArray.getString(jsonArray.size()-3);
+
+                record.setHierarchyName( name);
+            }else {
+                // 取出倒数第4个
+                String name = jsonArray.getString(jsonArray.size()-4);
+
+                record.setHierarchyName( name);
+            }
+
+        }
+
+        // 算出跨度几个月
+        int months = calculateMonthsBetween(query.getStartTime(),query.getEndTime());
+
+
+        ArrayList<ProjectHiddenDangerList> projectHiddenDangerLists = new ArrayList<>();
+
+        Map<String, List<Record>> map = list.stream().collect(groupingBy(Record::getHierarchyName));
+        for (Map.Entry<String, List<Record>> stringListEntry : map.entrySet()) {
+            String key = stringListEntry.getKey();
+            if(query.getContent()!=null && !query.getContent().isEmpty()){
+                if(!key.contains( query.getContent())){
+                    continue;
+                }
+            }
+
+            List<Record> value = stringListEntry.getValue();
+            ProjectHiddenDangerList projectHiddenDangerList1 = new ProjectHiddenDangerList();
+            projectHiddenDangerList1.setName(key);
+            ArrayList<ProjectHiddenDangerNextList> projectHiddenDangerNextLists = new ArrayList<>();
+            for (int i = 0; i < months; i++) {
+                ProjectHiddenDangerNextList projectHiddenDangerNextList = new ProjectHiddenDangerNextList();
+                LocalDate localDate = getMonthBoundaries(query.getStartTime(), true).plusMonths(i);
+                String dateStr = localDate.toString().substring(0, 7);
+                long count = value.stream().filter(record -> record.getCreateTime().toString().contains(dateStr)).count();
+                ProjectHiddenDangerList projectHiddenDangerList = new ProjectHiddenDangerList();
+                projectHiddenDangerList.setName(key);
+                projectHiddenDangerNextList.setTime(dateStr);
+                projectHiddenDangerNextList.setNum((int) count);
+                projectHiddenDangerNextLists.add(projectHiddenDangerNextList);
+            }
+            projectHiddenDangerList1.setList(projectHiddenDangerNextLists);
+            projectHiddenDangerLists.add(projectHiddenDangerList1);
+        }
+
+        return projectHiddenDangerLists;
+
+    }
+
+    @Override
+    public List<ProjectDangerousTrendVo> getProjectDangerousTrend(ProjectDangerousTrendQuery query) {
+        List<ProjectDangerousTrendVo> list = new ArrayList<>();
+        Project project = projectService.getById(query.getProjectId());
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        // 算出跨度几个月
+        int months = calculateMonthsBetween(query.getStartTime(),query.getEndTime());
+        ArrayList<Project> projects = new ArrayList<>();
+        projects.add( project);
+        String temp=null;
+        try {
+            for (int i = 0; i < months; i++) {
+                ProjectDangerousTrendVo vo = new ProjectDangerousTrendVo();
+                LocalDate localDate = getMonthBoundaries(query.getStartTime(), true).plusMonths(i);
+                String dateStr = localDate.toString().substring(0, 7);
+                String start = localDate+" 00:00:00";
+                String end = getMonthBoundaries(query.getStartTime(), false).plusMonths(i)+" 23:59:59";
+                Date startDate = simpleDateFormat.parse(start);
+                Date endDate = simpleDateFormat.parse(end);
+                vo.setTime(dateStr);
+
+                if(project.getType()==2){
+                    Map<Integer, String> integerStringMap = projectCategoryCalculator.calculateFixedAssetCategories(projects, Long.valueOf(project.getClientId()), startDate, endDate);
+                    String s = integerStringMap.get(query.getProjectId());
+                    vo.setLevel(s);
+                }else {
+                    Map<Integer, String> integerStringMap = projectCategoryCalculator.calculateOngoingProjectCategories(projects, Long.valueOf(project.getClientId()), startDate, endDate);
+                    String s = integerStringMap.get(query.getProjectId());
+                    vo.setLevel(s);
+                }
+                // 如果没有则沿用上次的
+                if(vo.getLevel()!=null){
+                    temp=vo.getLevel();
+                }else {
+                    vo.setLevel(temp);
+                }
+                list.add( vo);
+            }
+        }catch (ParseException e){
+            e.printStackTrace();
+        }
+
+        return list;
+    }
+
+
+    public static LocalDate getMonthBoundaries(String yearMonthStr,boolean isInclusive) {
+        // 解析字符串为YearMonth
+        YearMonth yearMonth = YearMonth.parse(yearMonthStr);
+        if(isInclusive){
+            // 获取第一天
+            LocalDate firstDay = yearMonth.atDay(1);
+            return firstDay;
+        }else {
+            // 获取最后一天
+            LocalDate lastDay = yearMonth.atEndOfMonth();
+            return lastDay;
+        }
+    }
+
+
+
+    public static int calculateMonthsBetween(String startYearMonth, String endYearMonth) {
+        YearMonth start = YearMonth.parse(startYearMonth);
+        YearMonth end = YearMonth.parse(endYearMonth);
+
+        // 计算月份差 + 1(包含结束月份)
+        return (int) ChronoUnit.MONTHS.between(start, end) + 1;
+    }
+    public static void main(String[] args) {
+        LocalDate monthBoundaries = getMonthBoundaries("2025-03", true);
+        System.out.println(monthBoundaries);
+        System.out.println(getMonthBoundaries("2025-02",false));
+
+        System.out.println(calculateMonthsBetween("2025-03", "2026-01"));
+
+        for (int count = 0; count < 11; count++) {
+            // 根据2025-03 根据循环获取下一个月的时间
+            LocalDate monthBoundaries1 = getMonthBoundaries("2025-03", true).plusMonths(count);
+            System.out.println(monthBoundaries1.toString().substring(0,7));
+        }
+    }
 }

--
Gitblit v1.7.1