package cn.huge.module.cases.utils;
|
|
import cn.huge.base.common.utils.DateUtils;
|
import cn.huge.base.common.utils.ObjectUtils;
|
import cn.huge.module.cases.domain.dto.CaseWorkStatisticsTimeDTO;
|
import com.alibaba.fastjson.JSON;
|
|
import java.time.*;
|
import java.time.format.DateTimeFormatter;
|
import java.time.temporal.TemporalAdjusters;
|
import java.util.*;
|
|
/**
|
* 工作统计-时间计算类
|
* @author zhouxiantao
|
* @create 2025-04-23 11:48
|
*/
|
public class StatisticsTimeUtils {
|
/**
|
* 判断两个时间 1-按日统计,2-按月统计,3-按年统计
|
* */
|
public static String spanTime(Date startDate, Date endDate){
|
Integer differDay = DateUtils.getDifferDay(startDate, endDate);
|
if(differDay <= 31){
|
return "1";
|
}else if(differDay > 31 && differDay <= 365){
|
return "2";
|
}else if(differDay > 365){
|
return "3";
|
}
|
return null;
|
}
|
|
|
/**
|
* 填补缺少的时间
|
* */
|
public static List<CaseWorkStatisticsTimeDTO> dellStatisticsTime(List<CaseWorkStatisticsTimeDTO> caseWorkStatisticsTimeDTOS, Date startDate, Date endDate,String type) {
|
List<CaseWorkStatisticsTimeDTO> resultList = new ArrayList<>();
|
if("1".equals(type)){
|
Integer differDay = DateUtils.getDifferDay(startDate, endDate);
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
LocalDate endLocalDate = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
// 生成所有在 startDate 和 endDate 范围内的日期
|
Set<LocalDate> allDatesInRange = new HashSet<>();
|
LocalDate currentDate = startLocalDate;
|
while (!currentDate.isAfter(endLocalDate)) {
|
allDatesInRange.add(currentDate);
|
currentDate = currentDate.plusDays(1);
|
}
|
// 将 caseWorkStatisticsTimeDTOs 中的日期转换为 LocalDate 并存储在 map 中
|
Map<LocalDate, CaseWorkStatisticsTimeDTO> existingDatesMap = new HashMap<>();
|
for (CaseWorkStatisticsTimeDTO dto : caseWorkStatisticsTimeDTOS) {
|
LocalDate date = LocalDate.parse(dto.getDayStr(), formatter);
|
existingDatesMap.put(date, dto);
|
}
|
// 确保每个日期都在范围内
|
for (LocalDate date : allDatesInRange) {
|
if (existingDatesMap.containsKey(date)) {
|
CaseWorkStatisticsTimeDTO caseWorkStatisticsTimeDTO = existingDatesMap.get(date);
|
String[] split = caseWorkStatisticsTimeDTO.getDayStr().split("-");
|
caseWorkStatisticsTimeDTO.setTimeStr(split[2]+"日");
|
caseWorkStatisticsTimeDTO.setTimeAllStr(split[0]+"年"+split[1]+"月"+split[2]+"日");
|
int i = Integer.valueOf(split[1]) * 100 + Integer.valueOf(split[2]);
|
caseWorkStatisticsTimeDTO.setSort(i);
|
resultList.add(caseWorkStatisticsTimeDTO);
|
} else {
|
String format = date.format(formatter);
|
String[] split = format.split("-");
|
CaseWorkStatisticsTimeDTO caseWorkStatisticsTimeDTO = new CaseWorkStatisticsTimeDTO();
|
caseWorkStatisticsTimeDTO.setTimeStr(split[2]+"日");
|
caseWorkStatisticsTimeDTO.setTimeAllStr(split[0]+"年"+split[1]+"月"+split[2]+"日");
|
int i = Integer.valueOf(split[1]) * 100 + Integer.valueOf(split[2]);
|
caseWorkStatisticsTimeDTO.setSort(i);
|
resultList.add(caseWorkStatisticsTimeDTO);
|
}
|
}
|
if(differDay <=7){
|
Collections.sort(resultList, (o1, o2) -> Integer.compare(o1.getSort(), o2.getSort()));
|
return resultList;
|
}else{
|
List<CaseWorkStatisticsTimeDTO> result1List = new ArrayList<>();
|
Map<String, List<CaseWorkStatisticsTimeDTO>> stringListMap = groupByWeek(caseWorkStatisticsTimeDTOS);
|
for (String week : stringListMap.keySet()) {
|
String[] split = week.split("=");
|
String[] startTime = split[0].split("-");
|
String[] endTime = split[1].split("-");
|
CaseWorkStatisticsTimeDTO caseWorkStatisticsTimeDTO = new CaseWorkStatisticsTimeDTO();
|
List<CaseWorkStatisticsTimeDTO> caseWorkStatisticsTimeDTOS1 = stringListMap.get(week);
|
for (CaseWorkStatisticsTimeDTO workStatisticsTimeDTO : caseWorkStatisticsTimeDTOS1) {
|
caseWorkStatisticsTimeDTO.setTotalNum(caseWorkStatisticsTimeDTO.getTotalNum()+workStatisticsTimeDTO.getTotalNum());
|
caseWorkStatisticsTimeDTO.setProcessNum(caseWorkStatisticsTimeDTO.getProcessNum()+workStatisticsTimeDTO.getProcessNum());
|
caseWorkStatisticsTimeDTO.setFinishNum(caseWorkStatisticsTimeDTO.getFinishNum()+workStatisticsTimeDTO.getFinishNum());
|
caseWorkStatisticsTimeDTO.setRejectNum(caseWorkStatisticsTimeDTO.getRejectNum()+workStatisticsTimeDTO.getRejectNum());
|
caseWorkStatisticsTimeDTO.setResolveNum(caseWorkStatisticsTimeDTO.getResolveNum()+workStatisticsTimeDTO.getResolveNum());
|
caseWorkStatisticsTimeDTO.setUnResolveNum(caseWorkStatisticsTimeDTO.getUnResolveNum()+workStatisticsTimeDTO.getUnResolveNum());
|
caseWorkStatisticsTimeDTO.setResolveingNum(caseWorkStatisticsTimeDTO.getResolveingNum()+workStatisticsTimeDTO.getResolveingNum());
|
}
|
caseWorkStatisticsTimeDTO.setTimeStr(startTime[2]+"-"+endTime[2]+"日");
|
caseWorkStatisticsTimeDTO.setTimeAllStr(startTime[0]+"年"+startTime[1]+"月"+startTime[2]+"-"+endTime[2]+"日");
|
int i = Integer.valueOf(startTime[1]) * 100 + Integer.valueOf(startTime[2]);
|
caseWorkStatisticsTimeDTO.setSort(i);
|
result1List.add(caseWorkStatisticsTimeDTO);
|
}
|
Collections.sort(result1List, (o1, o2) -> Integer.compare(o1.getSort(), o2.getSort()));
|
return result1List;
|
}
|
}else if("2".equals(type)){
|
int startYear = DateUtils.getYear(startDate);
|
int endYear = DateUtils.getYear(endDate);
|
int startMonth = DateUtils.getMonth(startDate);
|
int endMonth = DateUtils.getMonth(endDate);
|
Integer minMonth = startYear * 100 + startMonth;
|
Integer maxMonth = endYear * 100 + endMonth;
|
List<String> monthList = new ArrayList<>();
|
Map<String, CaseWorkStatisticsTimeDTO> existingDatesMap = new HashMap<>();
|
for (CaseWorkStatisticsTimeDTO caseWorkStatisticsTimeDTO : caseWorkStatisticsTimeDTOS) {
|
existingDatesMap.put(caseWorkStatisticsTimeDTO.getMonthStr(), caseWorkStatisticsTimeDTO);
|
monthList.add(caseWorkStatisticsTimeDTO.getMonthStr());
|
}
|
for (int i = minMonth; i <= maxMonth; i++){
|
Integer year = i / 100;
|
Integer month = i % 100;
|
if(month == 0 || month > 12){
|
continue;
|
}
|
String timeStr = year+"-"+month;
|
if(!monthList.contains(timeStr)){
|
CaseWorkStatisticsTimeDTO caseWorkStatisticsTimeDTO = new CaseWorkStatisticsTimeDTO();
|
caseWorkStatisticsTimeDTO.setTimeStr(month+"月");
|
caseWorkStatisticsTimeDTO.setTimeAllStr(year+"年"+month+"月");
|
caseWorkStatisticsTimeDTO.setSort(i);
|
resultList.add(caseWorkStatisticsTimeDTO);
|
}else{
|
CaseWorkStatisticsTimeDTO caseWorkStatisticsTimeDTO = existingDatesMap.get(timeStr);
|
caseWorkStatisticsTimeDTO.setTimeStr(month+"月");
|
caseWorkStatisticsTimeDTO.setTimeAllStr(year+"年"+month+"月");
|
caseWorkStatisticsTimeDTO.setSort(i);
|
resultList.add(caseWorkStatisticsTimeDTO);
|
}
|
}
|
}else {
|
int minYear = DateUtils.getYear(startDate);
|
int maxYear = DateUtils.getYear(endDate);
|
List<String> yearList = new ArrayList<>();
|
Map<String, CaseWorkStatisticsTimeDTO> existingDatesMap = new HashMap<>();
|
for (CaseWorkStatisticsTimeDTO caseWorkStatisticsTimeDTO : caseWorkStatisticsTimeDTOS) {
|
caseWorkStatisticsTimeDTO.setTimeStr(caseWorkStatisticsTimeDTO.getYearStr());
|
existingDatesMap.put(caseWorkStatisticsTimeDTO.getYearStr(), caseWorkStatisticsTimeDTO);
|
yearList.add(caseWorkStatisticsTimeDTO.getYearStr());
|
}
|
for (int i = minYear; i <= maxYear; i++){
|
String timeStr = String.valueOf(i);
|
if(!yearList.contains(timeStr)){
|
CaseWorkStatisticsTimeDTO caseWorkStatisticsTimeDTO = new CaseWorkStatisticsTimeDTO();
|
caseWorkStatisticsTimeDTO.setTimeStr(timeStr+"年");
|
caseWorkStatisticsTimeDTO.setTimeAllStr(timeStr+"年");
|
caseWorkStatisticsTimeDTO.setSort(i);
|
resultList.add(caseWorkStatisticsTimeDTO);
|
}else{
|
CaseWorkStatisticsTimeDTO caseWorkStatisticsTimeDTO = existingDatesMap.get(timeStr);
|
caseWorkStatisticsTimeDTO.setTimeStr(timeStr+"年");
|
caseWorkStatisticsTimeDTO.setTimeAllStr(timeStr+"年");
|
caseWorkStatisticsTimeDTO.setSort(i);
|
resultList.add(caseWorkStatisticsTimeDTO);
|
}
|
}
|
}
|
Collections.sort(resultList, (o1, o2) -> Integer.compare(o1.getSort(), o2.getSort()));
|
return resultList;
|
}
|
|
/**
|
* 按周进行分组
|
* */
|
public static Map<String, List<CaseWorkStatisticsTimeDTO>> groupByWeek(List<CaseWorkStatisticsTimeDTO> caseWorkStatisticsTimeDTOs) {
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
Map<String, List<CaseWorkStatisticsTimeDTO>> weeklyGroups = new HashMap<>();
|
for (CaseWorkStatisticsTimeDTO dto : caseWorkStatisticsTimeDTOs) {
|
LocalDate date = LocalDate.parse(dto.getDayStr(), formatter);
|
LocalDate startOfWeek = date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
|
LocalDate endOfWeek = date.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
|
String weekKey = startOfWeek.format(formatter) + "=" + endOfWeek.format(formatter);
|
weeklyGroups.computeIfAbsent(weekKey, k -> new ArrayList<>()).add(dto);
|
}
|
// 对每个周组内的记录按时间从小到大排序
|
for (List<CaseWorkStatisticsTimeDTO> group : weeklyGroups.values()) {
|
group.sort(Comparator.comparing(CaseWorkStatisticsTimeDTO::getDayStr));
|
}
|
System.out.println(JSON.toJSONString(weeklyGroups));
|
return weeklyGroups;
|
}
|
|
public static boolean isStartAndEndOfYear(Date startDate, Date endDate) {
|
LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
LocalDate endLocalDate = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
// 判断 startDate 是否是某一年的第一天
|
boolean isStartDateFirstDay = startLocalDate.equals(startLocalDate.with(TemporalAdjusters.firstDayOfYear()));
|
// 判断 endDate 是否是某一年的最后一天
|
boolean isEndDateLastDay = endLocalDate.equals(endLocalDate.with(TemporalAdjusters.lastDayOfYear()));
|
return isStartDateFirstDay && isEndDateLastDay && startLocalDate.getYear() == endLocalDate.getYear();
|
}
|
|
public static boolean isStartAndEndOfMonth(Date startDate, Date endDate) {
|
LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
LocalDate endLocalDate = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
// 判断 startDate 是否是某个月的第一天
|
boolean isStartDateFirstDay = startLocalDate.equals(startLocalDate.with(TemporalAdjusters.firstDayOfMonth()));
|
// 判断 endDate 是否是某个月的最后一天
|
boolean isEndDateLastDay = endLocalDate.equals(endLocalDate.with(TemporalAdjusters.lastDayOfMonth()));
|
return isStartDateFirstDay && isEndDateLastDay && startLocalDate.getMonthValue() == endLocalDate.getMonthValue() && startLocalDate.getYear() == endLocalDate.getYear();
|
}
|
|
/**
|
* 获取时间的上个月开始时间
|
* */
|
public static String getMomStartDate(Date startDate) {
|
LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
YearMonth lastMonth = YearMonth.from(startLocalDate).minusMonths(1);
|
LocalDate firstDayOfLastMonth = lastMonth.atDay(1);
|
Date from = Date.from(firstDayOfLastMonth.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
String time = DateUtils.DateToString(from, DateUtils.YYYY_MM_DD);
|
return time;
|
}
|
|
/**
|
* 获取时间的上个月结束时间
|
* */
|
public static String getMomEndDate(Date startDate) {
|
LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
YearMonth lastMonth = YearMonth.from(startLocalDate).minusMonths(1);
|
LocalDate lastDayOfLastMonth = lastMonth.atEndOfMonth();
|
Date from = Date.from(lastDayOfLastMonth.atTime(23, 59, 59).atZone(ZoneId.systemDefault()).toInstant());
|
String time = DateUtils.DateToString(from, DateUtils.YYYY_MM_DD);
|
return time;
|
}
|
|
/**
|
* 获取时间的去年的时间
|
* */
|
public static String getYoyDate(Date startDate) {
|
LocalDateTime startDateTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
LocalDateTime lastYearSameDateTime = startDateTime.minusYears(1);
|
Date from = Date.from(lastYearSameDateTime.atZone(ZoneId.systemDefault()).toInstant());
|
String time = DateUtils.DateToString(from, DateUtils.YYYY_MM_DD);
|
return time;
|
}
|
|
public static String calculateMomGrowthRate(int currentMonthValue, int previousMonthValue) {
|
if (previousMonthValue == 0) {
|
return "0";
|
}
|
double rate = ((double) (currentMonthValue - previousMonthValue) / previousMonthValue) * 100;
|
return String.format("%.1f", rate);
|
}
|
|
public static String calculateMomGrowthRate(String currentStr, String previousStr) {
|
if(ObjectUtils.isEmpty(currentStr)){
|
return "0";
|
}
|
double previousMonthValue = 0;
|
if(ObjectUtils.isNotEmpty(previousStr) && !"null".equals(previousStr)){
|
previousMonthValue = Double.valueOf(previousStr);
|
}
|
double currentMonthValue = Double.valueOf(currentStr);
|
if(currentMonthValue == 0){
|
return "0";
|
}
|
double rate = ((double) (currentMonthValue - previousMonthValue) / previousMonthValue) * 100;
|
return String.format("%.1f", rate);
|
}
|
|
}
|