增加告警年统计、月统计接口,增加设备列表接口
This commit is contained in:
parent
94953eb330
commit
4cda521e81
|
|
@ -0,0 +1,128 @@
|
||||||
|
package org.jeecg.modules.appmana.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.config.TenantContext;
|
||||||
|
import org.jeecg.common.constant.PollutionConstants;
|
||||||
|
import org.jeecg.common.dto.AlertSummaryDTO;
|
||||||
|
import org.jeecg.common.entity.SurvDeviceDeploy;
|
||||||
|
import org.jeecg.common.entity.SurvDisplayInfo;
|
||||||
|
import org.jeecg.common.entity.SurvPestlightAlert;
|
||||||
|
import org.jeecg.common.entity.SurvStationInfo;
|
||||||
|
import org.jeecg.common.util.DateTimeRangeUtil;
|
||||||
|
import org.jeecg.common.vo.PestLightAlertVo;
|
||||||
|
import org.jeecg.common.vo.result.DataCenterDataSummary;
|
||||||
|
import org.jeecg.common.vo.statistic.AlertSummaryVo;
|
||||||
|
import org.jeecg.modules.appmana.service.ISurvAlertRecordService;
|
||||||
|
import org.jeecg.modules.appmana.service.ISurvDeviceDeployService;
|
||||||
|
import org.jeecg.modules.appmana.service.ISurvPestlightAlertService;
|
||||||
|
import org.jeecg.modules.appmana.service.ISurvStationInfoService;
|
||||||
|
import org.jeecg.modules.appmana.service.impl.CommonServiceImpl;
|
||||||
|
import org.jeecg.modules.appmana.service.impl.IotCommonP3ServiceImpl;
|
||||||
|
import org.jeecg.modules.appmana.utils.MonitoringDataRichTextBuilder;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Api(tags="公共接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/appmana/dataCenter")
|
||||||
|
@Slf4j
|
||||||
|
public class DataCenterController {
|
||||||
|
@Autowired
|
||||||
|
private ISurvDeviceDeployService survDeviceDeployService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommonServiceImpl commonService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISurvAlertRecordService survAlertRecordService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISurvStationInfoService survStationInfoService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有大屏信息
|
||||||
|
*/
|
||||||
|
@GetMapping(value = "/dataSummary")
|
||||||
|
public Result<DataCenterDataSummary> dataSummary() {
|
||||||
|
DataCenterDataSummary re = new DataCenterDataSummary();
|
||||||
|
//当前租户所有设备
|
||||||
|
List<SurvDeviceDeploy> deviceList = survDeviceDeployService.lambdaQuery()
|
||||||
|
.list();
|
||||||
|
LocalDateTime weekStart = DateTimeRangeUtil.getWeekStart();
|
||||||
|
LocalDateTime weekEnd = DateTimeRangeUtil.getWeekEnd();
|
||||||
|
|
||||||
|
LocalDateTime monthStart = DateTimeRangeUtil.getMonthStart();
|
||||||
|
LocalDateTime monthEnd = DateTimeRangeUtil.getMonthEnd();
|
||||||
|
|
||||||
|
LocalDateTime yearStart = DateTimeRangeUtil.getYearStart();
|
||||||
|
LocalDateTime yearEnd = DateTimeRangeUtil.getYearEnd();
|
||||||
|
|
||||||
|
|
||||||
|
re.setWeekHtml(commonService.buildDeviceReport(deviceList,weekStart,weekEnd));
|
||||||
|
re.setMonthHtml(commonService.buildDeviceReport(deviceList,monthStart,monthEnd));
|
||||||
|
re.setYearHtml(commonService.buildDeviceReport(deviceList,yearStart,yearEnd));
|
||||||
|
return Result.OK(re);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备统计监测统计数据
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/deviceAlertStatistic")
|
||||||
|
public Result<AlertSummaryVo> deviceAlertStatistic(@RequestBody AlertSummaryDTO alertSummaryDTO) {
|
||||||
|
|
||||||
|
alertSummaryDTO.setTenantId(TenantContext.getTenant());
|
||||||
|
AlertSummaryVo alertSummaryVo = survAlertRecordService.getSummary(alertSummaryDTO);
|
||||||
|
return Result.OK(alertSummaryVo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有设备数据
|
||||||
|
*/
|
||||||
|
@GetMapping(value = "/deviceList")
|
||||||
|
public Result< List<SurvDeviceDeploy>> deviceList() {
|
||||||
|
List<String> deployTypes = new ArrayList<>();
|
||||||
|
deployTypes.add(PollutionConstants.SOIL_SURV);
|
||||||
|
deployTypes.add(PollutionConstants.AIR_SURV);
|
||||||
|
deployTypes.add(PollutionConstants.WATER_QULITY);
|
||||||
|
deployTypes.add(PollutionConstants.STINK);
|
||||||
|
deployTypes.add(PollutionConstants.WATER_LIVE);
|
||||||
|
deployTypes.add(PollutionConstants.WATER_ORIENT);
|
||||||
|
|
||||||
|
List<SurvDeviceDeploy> deviceList = survDeviceDeployService.lambdaQuery()
|
||||||
|
.in(SurvDeviceDeploy::getDeployType,deployTypes)
|
||||||
|
.orderByDesc(SurvDeviceDeploy::getDeployType)
|
||||||
|
.orderByAsc(SurvDeviceDeploy::getSortNo)
|
||||||
|
.orderByDesc(SurvDeviceDeploy::getCreateTime)
|
||||||
|
.list();
|
||||||
|
if(deviceList!=null){
|
||||||
|
List<SurvStationInfo> stationList = survStationInfoService.list();
|
||||||
|
Map<String,SurvStationInfo> stationInfoMap = new HashMap<>();
|
||||||
|
stationList.forEach(item->{
|
||||||
|
stationInfoMap.put(item.getStationCode(),item);
|
||||||
|
});
|
||||||
|
deviceList.forEach(item->{
|
||||||
|
SurvStationInfo stationInfo = stationInfoMap.get(item.getStationCode());
|
||||||
|
if(stationInfo!=null){
|
||||||
|
item.setDeployDes(stationInfo.getStationName()+" - " + item.getDeployDes());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Result.OK(deviceList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -168,4 +169,15 @@ public class SurvDisplayInfoController extends JeecgController<SurvDisplayInfo,
|
||||||
return super.importExcel(request, response, SurvDisplayInfo.class);
|
return super.importExcel(request, response, SurvDisplayInfo.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有大屏信息
|
||||||
|
*/
|
||||||
|
@GetMapping(value = "/getQualityData")
|
||||||
|
public Result<SurvDisplayInfo> getQualityData(@RequestParam String infoKey) {
|
||||||
|
List<SurvDisplayInfo> dis5 = survDisplayInfoService.getInfoByType(infoKey);
|
||||||
|
SurvDisplayInfo re = dis5.size()>0?dis5.get(0):null;
|
||||||
|
return Result.OK(re);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.jeecg.common.entity.SurvAlertRecord;
|
import org.jeecg.common.entity.SurvAlertRecord;
|
||||||
|
import org.jeecg.common.vo.statistic.AlertSummayDetail;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -20,4 +22,22 @@ public interface SurvAlertRecordMapper extends BaseMapper<SurvAlertRecord> {
|
||||||
|
|
||||||
IPage<SurvAlertRecord> pageByDevice(IPage<SurvAlertRecord> page, @Param("deviceList") List<String> deviceList, @Param("yearStr") String yearStr);
|
IPage<SurvAlertRecord> pageByDevice(IPage<SurvAlertRecord> page, @Param("deviceList") List<String> deviceList, @Param("yearStr") String yearStr);
|
||||||
|
|
||||||
|
List<AlertSummayDetail> getSpotCheckData(@Param("deployId")String deployId,@Param("itemCode")String itemCode, @Param("dateList") List<String> dateList,@Param("startDateTime")LocalDateTime startDateTime,@Param("endDateTime")LocalDateTime endDateTime);
|
||||||
|
|
||||||
|
List<AlertSummayDetail> getDailyMaxSpotCheckData(
|
||||||
|
@Param("dateList") List<String> dateList,
|
||||||
|
@Param("startDateTime") LocalDateTime startDateTime,
|
||||||
|
@Param("endDateTime") LocalDateTime endDateTime,
|
||||||
|
@Param("deployId") String deployId,
|
||||||
|
@Param("itemCode") String itemCode
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
List<AlertSummayDetail> getMonthMaxSpotCheckData(
|
||||||
|
@Param("dateList") List<String> dateList,
|
||||||
|
@Param("startDateTime") LocalDateTime startDateTime,
|
||||||
|
@Param("endDateTime") LocalDateTime endDateTime,
|
||||||
|
@Param("deployId") String deployId,
|
||||||
|
@Param("itemCode") String itemCode
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,7 @@ public interface SurvDeviceDeployMapper extends BaseMapper<SurvDeviceDeploy> {
|
||||||
|
|
||||||
@InterceptorIgnore(illegalSql = "true", tenantLine = "true")
|
@InterceptorIgnore(illegalSql = "true", tenantLine = "true")
|
||||||
SurvDeviceDeploy getDeviceById(@Param("deployId")String deployId, @Param("tenantId")String tenantId);
|
SurvDeviceDeploy getDeviceById(@Param("deployId")String deployId, @Param("tenantId")String tenantId);
|
||||||
|
|
||||||
|
@InterceptorIgnore(illegalSql = "true", tenantLine = "true")
|
||||||
|
SurvDeviceDeploy getDeployZhibiao(@Param("deployId")String deployId, @Param("tenantId")String tenantId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,4 +77,108 @@
|
||||||
</where>
|
</where>
|
||||||
order by ALERT_TIME desc
|
order by ALERT_TIME desc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
<select id="getSpotCheckData" resultType="org.jeecg.common.vo.statistic.AlertSummayDetail">
|
||||||
|
SELECT
|
||||||
|
ti.interval_start as alertTime,
|
||||||
|
COALESCE(ad.ID, 0) as id,
|
||||||
|
COALESCE(ad.DEPLOY_ID, #{deployId}) as deployId,
|
||||||
|
COALESCE(ad.NORMAL_VALUE, 0) as normalValue,
|
||||||
|
COALESCE(ad.SURV_VALUE, 0) as survValue,
|
||||||
|
COALESCE(ad.ITEM_CODE, #{itemCode}) as itemCode,
|
||||||
|
CASE WHEN ad.ALERT_TIME IS NULL THEN 0 ELSE 1 END as hasData
|
||||||
|
FROM (
|
||||||
|
<foreach item="items" collection="dateList" separator="union all">
|
||||||
|
SELECT CAST(#{items} AS DATETIME) as interval_start
|
||||||
|
</foreach>
|
||||||
|
) ti
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT
|
||||||
|
t.*,
|
||||||
|
ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY DATE(t.ALERT_TIME), HOUR(t.ALERT_TIME), FLOOR(MINUTE(t.ALERT_TIME) / 15)
|
||||||
|
ORDER BY t.ALERT_TIME ASC
|
||||||
|
) AS rn
|
||||||
|
FROM surv_alert_record t
|
||||||
|
WHERE t.ALERT_TIME >= #{startDateTime}
|
||||||
|
AND t.ALERT_TIME <= #{endDateTime}
|
||||||
|
AND t.DEPLOY_ID = #{deployId}
|
||||||
|
AND t.ITEM_CODE = #{itemCode}
|
||||||
|
) temp
|
||||||
|
WHERE temp.rn = 1
|
||||||
|
) ad ON ad.ALERT_TIME >= ti.interval_start
|
||||||
|
AND ad.ALERT_TIME < DATE_ADD(ti.interval_start, INTERVAL 5 MINUTE)
|
||||||
|
ORDER BY ti.interval_start;
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="getDailyMaxSpotCheckData" resultType="org.jeecg.common.vo.statistic.AlertSummayDetail">
|
||||||
|
SELECT
|
||||||
|
ti.interval_start as alertTime,
|
||||||
|
COALESCE(ad.ID, 0) as id,
|
||||||
|
COALESCE(ad.DEPLOY_ID, #{deployId}) as deployId,
|
||||||
|
COALESCE(ad.NORMAL_VALUE, 0) as normalValue,
|
||||||
|
COALESCE(ad.SURV_VALUE, 0) as survValue,
|
||||||
|
COALESCE(ad.ITEM_CODE, #{itemCode}) as itemCode,
|
||||||
|
CASE WHEN ad.ALERT_TIME IS NULL THEN 0 ELSE 1 END as hasData
|
||||||
|
FROM (
|
||||||
|
<foreach item="items" collection="dateList" separator="union all">
|
||||||
|
SELECT CAST(#{items} AS DATE) as interval_start
|
||||||
|
</foreach>
|
||||||
|
) ti
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT
|
||||||
|
t.*,
|
||||||
|
ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY DATE(t.ALERT_TIME)
|
||||||
|
ORDER BY CAST(t.SURV_VALUE AS DECIMAL(18,2)) DESC, t.ALERT_TIME ASC
|
||||||
|
) AS rn
|
||||||
|
FROM surv_alert_record t
|
||||||
|
WHERE t.ALERT_TIME >= #{startDateTime}
|
||||||
|
AND t.ALERT_TIME <= #{endDateTime}
|
||||||
|
AND t.DEPLOY_ID = #{deployId}
|
||||||
|
AND t.ITEM_CODE = #{itemCode}
|
||||||
|
) temp
|
||||||
|
WHERE temp.rn = 1
|
||||||
|
) ad ON DATE(ad.ALERT_TIME) = ti.interval_start
|
||||||
|
ORDER BY ti.interval_start;
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 按月查询,取每月 SURV_VALUE 最大的记录 -->
|
||||||
|
<select id="getMonthMaxSpotCheckData" resultType="org.jeecg.common.vo.statistic.AlertSummayDetail">
|
||||||
|
SELECT
|
||||||
|
ti.interval_start as alertTime,
|
||||||
|
COALESCE(ad.ID, 0) as id,
|
||||||
|
COALESCE(ad.DEPLOY_ID, #{deployId}) as deployId,
|
||||||
|
COALESCE(ad.NORMAL_VALUE, 0) as normalValue,
|
||||||
|
COALESCE(ad.SURV_VALUE, 0) as survValue,
|
||||||
|
COALESCE(ad.ITEM_CODE, #{itemCode}) as itemCode,
|
||||||
|
CASE WHEN ad.ALERT_TIME IS NULL THEN 0 ELSE 1 END as hasData
|
||||||
|
FROM (
|
||||||
|
<foreach item="items" collection="dateList" separator="union all">
|
||||||
|
-- 支持 yyyy-MM 和 yyyy-MM-dd 两种格式
|
||||||
|
SELECT CAST(CONCAT(#{items}, IF(LENGTH(#{items}) = 7, '-01', '')) AS DATE) as interval_start
|
||||||
|
</foreach>
|
||||||
|
) ti
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT
|
||||||
|
t.*,
|
||||||
|
ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY YEAR(t.ALERT_TIME), MONTH(t.ALERT_TIME)
|
||||||
|
ORDER BY CAST(t.SURV_VALUE AS DECIMAL(18,2)) DESC, t.ALERT_TIME ASC
|
||||||
|
) AS rn
|
||||||
|
FROM surv_alert_record t
|
||||||
|
WHERE t.ALERT_TIME >= #{startDateTime}
|
||||||
|
AND t.ALERT_TIME <= #{endDateTime}
|
||||||
|
AND t.DEPLOY_ID = #{deployId}
|
||||||
|
AND t.ITEM_CODE = #{itemCode}
|
||||||
|
) temp
|
||||||
|
WHERE temp.rn = 1
|
||||||
|
) ad ON YEAR(ad.ALERT_TIME) = YEAR(ti.interval_start)
|
||||||
|
AND MONTH(ad.ALERT_TIME) = MONTH(ti.interval_start)
|
||||||
|
ORDER BY ti.interval_start;
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
@ -147,4 +147,8 @@
|
||||||
<select id="getDeviceById" resultType="org.jeecg.common.entity.SurvDeviceDeploy">
|
<select id="getDeviceById" resultType="org.jeecg.common.entity.SurvDeviceDeploy">
|
||||||
select <include refid="basesql"/> from surv_device_deploy where IS_DEL = 0 AND ID = #{deployId} AND TENANT_ID = #{tenantId} limit 1
|
select <include refid="basesql"/> from surv_device_deploy where IS_DEL = 0 AND ID = #{deployId} AND TENANT_ID = #{tenantId} limit 1
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="getDeployZhibiao" resultMap="zhibiaoMap">
|
||||||
|
select <include refid="basesql"/> from surv_device_deploy where IS_DEL = 0 AND ID = #{deployId} AND TENANT_ID = #{tenantId} limit 1
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
@ -2,7 +2,9 @@ package org.jeecg.modules.appmana.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.jeecg.common.dto.AlertSummaryDTO;
|
||||||
import org.jeecg.common.entity.SurvAlertRecord;
|
import org.jeecg.common.entity.SurvAlertRecord;
|
||||||
|
import org.jeecg.common.vo.statistic.AlertSummaryVo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -17,4 +19,6 @@ public interface ISurvAlertRecordService extends IService<SurvAlertRecord> {
|
||||||
IPage<SurvAlertRecord> pages(IPage<SurvAlertRecord> page, SurvAlertRecord survAlertRecord);
|
IPage<SurvAlertRecord> pages(IPage<SurvAlertRecord> page, SurvAlertRecord survAlertRecord);
|
||||||
|
|
||||||
IPage<SurvAlertRecord> pageByDevice(IPage<SurvAlertRecord> page, List<String> deviceList, String yearStr);
|
IPage<SurvAlertRecord> pageByDevice(IPage<SurvAlertRecord> page, List<String> deviceList, String yearStr);
|
||||||
|
|
||||||
|
AlertSummaryVo getSummary(AlertSummaryDTO alertSummaryDTO);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,4 +37,6 @@ public interface ISurvDeviceDeployService extends IService<SurvDeviceDeploy> {
|
||||||
SurvDeviceDeploy getOrientDeviceByStation(String stationCode);
|
SurvDeviceDeploy getOrientDeviceByStation(String stationCode);
|
||||||
|
|
||||||
SurvDeviceDeploy getDeviceById(String deployId,String tenantId);
|
SurvDeviceDeploy getDeviceById(String deployId,String tenantId);
|
||||||
|
|
||||||
|
SurvDeviceDeploy getDeployZhibiao(String deployId, String tenantId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,34 @@
|
||||||
package org.jeecg.modules.appmana.service.impl;
|
package org.jeecg.modules.appmana.service.impl;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.beanutils.BeanUtils;
|
import org.apache.commons.beanutils.BeanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jeecg.common.config.TenantContext;
|
import org.jeecg.common.config.TenantContext;
|
||||||
import org.jeecg.common.constant.CommonConstants;
|
import org.jeecg.common.constant.CommonConstants;
|
||||||
|
import org.jeecg.common.constant.DeviceReadConstants;
|
||||||
import org.jeecg.common.constant.PollutionConstants;
|
import org.jeecg.common.constant.PollutionConstants;
|
||||||
import org.jeecg.common.constant.enums.PollutionEnum;
|
import org.jeecg.common.constant.enums.PollutionEnum;
|
||||||
import org.jeecg.common.dto.CommonDTO;
|
import org.jeecg.common.dto.CommonDTO;
|
||||||
import org.jeecg.common.entity.*;
|
import org.jeecg.common.entity.*;
|
||||||
import org.jeecg.common.vo.VOHisResult;
|
import org.jeecg.common.vo.VOHisResult;
|
||||||
|
import org.jeecg.common.vo.statistic.AlertReport;
|
||||||
import org.jeecg.common.vo.statistic.ScreenIndexSummaryDetailVo;
|
import org.jeecg.common.vo.statistic.ScreenIndexSummaryDetailVo;
|
||||||
import org.jeecg.modules.appmana.service.ISurvHisdataAirService;
|
import org.jeecg.modules.appmana.service.*;
|
||||||
import org.jeecg.modules.appmana.service.ISurvHisdataLivestockwaterService;
|
|
||||||
import org.jeecg.modules.appmana.service.ISurvHisdataOrientwaterService;
|
|
||||||
import org.jeecg.modules.appmana.service.ISurvHisdataSoilService;
|
|
||||||
import org.jeecg.modules.appmana.utils.HttpServletRequestUtil;
|
import org.jeecg.modules.appmana.utils.HttpServletRequestUtil;
|
||||||
|
import org.jeecg.modules.appmana.utils.MonitoringDataRichTextBuilder;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|
@ -37,6 +38,8 @@ public class CommonServiceImpl {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISurvHisdataSoilService hisdataSoilService;
|
private ISurvHisdataSoilService hisdataSoilService;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private ISurvHisdataVocsService vocsService;
|
||||||
|
@Autowired
|
||||||
private ISurvHisdataOrientwaterService hisdataOrientwaterService;
|
private ISurvHisdataOrientwaterService hisdataOrientwaterService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISurvHisdataLivestockwaterService hisdataLivestockwaterService;
|
private ISurvHisdataLivestockwaterService hisdataLivestockwaterService;
|
||||||
|
|
@ -47,6 +50,11 @@ public class CommonServiceImpl {
|
||||||
@Autowired
|
@Autowired
|
||||||
@Lazy
|
@Lazy
|
||||||
private ScEquZhibiaoServiceImpl zhibiaoService;
|
private ScEquZhibiaoServiceImpl zhibiaoService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private ISurvAlertRecordService alertRecordService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取监测设备的数据
|
* 获取监测设备的数据
|
||||||
*/
|
*/
|
||||||
|
|
@ -248,4 +256,206 @@ public class CommonServiceImpl {
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造设备的数据报告
|
||||||
|
*/
|
||||||
|
public String buildDeviceReport(List<SurvDeviceDeploy> deploys,LocalDateTime startTime,LocalDateTime endTime){
|
||||||
|
/**
|
||||||
|
* 遍历设备类型,根据设备类型查询数据
|
||||||
|
*/
|
||||||
|
List<String> airList = new ArrayList<>();
|
||||||
|
List<String> soilList = new ArrayList<>();
|
||||||
|
List<String> waterList = new ArrayList<>();
|
||||||
|
List<String> orientIdList = new ArrayList<>();
|
||||||
|
List<String> liveIdList = new ArrayList<>();
|
||||||
|
List<String> stinkIdList = new ArrayList<>();
|
||||||
|
|
||||||
|
List<String> totalList = new ArrayList<>();
|
||||||
|
for (SurvDeviceDeploy survDeviceDeploy : deploys) {
|
||||||
|
if (PollutionConstants.SOIL_SURV.equals(survDeviceDeploy.getDeployType())) {//土壤设备
|
||||||
|
soilList.add(survDeviceDeploy.getId());
|
||||||
|
totalList.add(survDeviceDeploy.getId());
|
||||||
|
} else if (PollutionConstants.AIR_SURV.equals(survDeviceDeploy.getDeployType())) {//气象设备
|
||||||
|
airList.add(survDeviceDeploy.getId());
|
||||||
|
totalList.add(survDeviceDeploy.getId());
|
||||||
|
} else if (PollutionConstants.WATER_QULITY.equals(survDeviceDeploy.getDeployType())) {//水质设备
|
||||||
|
waterList.add(survDeviceDeploy.getId());
|
||||||
|
totalList.add(survDeviceDeploy.getId());
|
||||||
|
}else if (PollutionConstants.WATER_ORIENT.equals(survDeviceDeploy.getDeployType())) {//面源
|
||||||
|
orientIdList.add(survDeviceDeploy.getId());
|
||||||
|
totalList.add(survDeviceDeploy.getId());
|
||||||
|
} else if (PollutionConstants.WATER_LIVE.equals(survDeviceDeploy.getDeployType())) {//畜禽
|
||||||
|
liveIdList.add(survDeviceDeploy.getId());
|
||||||
|
totalList.add(survDeviceDeploy.getId());
|
||||||
|
} else if (PollutionConstants.STINK.equals(survDeviceDeploy.getDeployType())) {//恶臭
|
||||||
|
stinkIdList.add(survDeviceDeploy.getId());
|
||||||
|
totalList.add(survDeviceDeploy.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Long dataCounts = 0L;
|
||||||
|
//step2 根据设备类型查询数据
|
||||||
|
if(!airList.isEmpty()){
|
||||||
|
dataCounts = dataCounts + hisdataAirService.count(new LambdaUpdateWrapper<SurvHisdataAir>()
|
||||||
|
.in(SurvHisdataAir::getDeployId, airList)
|
||||||
|
.between(SurvHisdataAir::getDataDateTime, startTime, endTime)
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if(!soilList.isEmpty()){
|
||||||
|
dataCounts = dataCounts + hisdataSoilService.count(new LambdaUpdateWrapper<SurvHisdataSoil>()
|
||||||
|
.in(SurvHisdataSoil::getDeployId, soilList)
|
||||||
|
.between(SurvHisdataSoil::getDataDateTime, startTime, endTime)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if(!waterList.isEmpty()){
|
||||||
|
dataCounts = dataCounts + hisdataSoilService.count(new LambdaUpdateWrapper<SurvHisdataSoil>()
|
||||||
|
.in(SurvHisdataSoil::getDeployId, waterList)
|
||||||
|
.between(SurvHisdataSoil::getDataDateTime, startTime, endTime)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if(!orientIdList.isEmpty()){
|
||||||
|
dataCounts = dataCounts + hisdataOrientwaterService.count(new LambdaUpdateWrapper<SurvHisdataOrientwater>()
|
||||||
|
.in(SurvHisdataOrientwater::getDeviceId, orientIdList)
|
||||||
|
.between(SurvHisdataOrientwater::getDataDateTime, startTime, endTime)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if(!liveIdList.isEmpty()){
|
||||||
|
dataCounts = dataCounts + hisdataLivestockwaterService.count(new LambdaUpdateWrapper<SurvHisdataLivestockwater>()
|
||||||
|
.in(SurvHisdataLivestockwater::getDeviceId, liveIdList)
|
||||||
|
.between(SurvHisdataLivestockwater::getDataDateTime, startTime, endTime)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if(!stinkIdList.isEmpty()){
|
||||||
|
dataCounts = dataCounts + vocsService.count(new LambdaUpdateWrapper<SurvHisdataVocs>()
|
||||||
|
.in(SurvHisdataVocs::getDeployId, stinkIdList)
|
||||||
|
.between(SurvHisdataVocs::getDataDateTime, startTime, endTime)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ScEquZhibiao> zhibiaoList = zhibiaoService.getAllChemical(totalList);
|
||||||
|
Map<String,String> zhibiaoMap = new HashMap<>();
|
||||||
|
if(!zhibiaoList.isEmpty()){
|
||||||
|
for (ScEquZhibiao scEquZhibiao : zhibiaoList) {
|
||||||
|
zhibiaoMap.put(scEquZhibiao.getEntityField(),scEquZhibiao.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//异常数据
|
||||||
|
Integer abnormalCount = 0;
|
||||||
|
|
||||||
|
List<SurvAlertRecord> alertRecordList = alertRecordService.lambdaQuery()
|
||||||
|
.between(SurvAlertRecord::getAlertTime, startTime, endTime)
|
||||||
|
.list();
|
||||||
|
Map<String, AlertReport> alertHighMap = new HashMap<>();
|
||||||
|
Map<String, AlertReport> alertLowMap = new HashMap<>();
|
||||||
|
List<String> unnormalList = new ArrayList<>();
|
||||||
|
if(!alertRecordList.isEmpty()){
|
||||||
|
abnormalCount = alertRecordList.size();
|
||||||
|
|
||||||
|
for (SurvAlertRecord survAlertRecord : alertRecordList) {
|
||||||
|
unnormalList.add(survAlertRecord.getItemCode());
|
||||||
|
|
||||||
|
if(DeviceReadConstants.READ_TOO_LOW.equals(survAlertRecord.getReadStatus())){
|
||||||
|
AlertReport alertReport = alertLowMap.get(survAlertRecord.getItemCode());
|
||||||
|
|
||||||
|
if(alertReport != null){
|
||||||
|
BigDecimal extremeValue = new BigDecimal(survAlertRecord.getSurvValue());//当前值
|
||||||
|
BigDecimal lastValue = new BigDecimal(alertReport.getExtremeValue());//上一个值
|
||||||
|
//对比上一个值,如果比上一个小,就更新为当前值
|
||||||
|
if(extremeValue.compareTo(lastValue) <= 0){
|
||||||
|
alertReport.setExtremeValue(extremeValue.toPlainString());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
alertReport = new AlertReport();
|
||||||
|
alertReport.setItemName(survAlertRecord.getItemName());
|
||||||
|
alertReport.setItemUnit(survAlertRecord.getSurvUnit());
|
||||||
|
alertReport.setExtremeValue(survAlertRecord.getSurvValue());
|
||||||
|
alertReport.setAlertCount(0);
|
||||||
|
}
|
||||||
|
alertReport.setAlertCount(alertReport.getAlertCount() + 1);
|
||||||
|
alertLowMap.put(survAlertRecord.getItemCode(),alertReport);
|
||||||
|
|
||||||
|
}else if(DeviceReadConstants.READ_TOO_HIGH.equals(survAlertRecord.getReadStatus())){
|
||||||
|
AlertReport alertHighReport = alertHighMap.get(survAlertRecord.getItemCode());
|
||||||
|
|
||||||
|
if(alertHighReport != null){
|
||||||
|
BigDecimal extremeValue = new BigDecimal(survAlertRecord.getSurvValue());//当前值
|
||||||
|
BigDecimal lastValue = new BigDecimal(alertHighReport.getExtremeValue());//上一个值
|
||||||
|
//对比上一个值,如果比上一个大,就更新为当前值
|
||||||
|
if(extremeValue.compareTo(lastValue) >= 0){
|
||||||
|
alertHighReport.setExtremeValue(extremeValue.toPlainString());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
alertHighReport = new AlertReport();
|
||||||
|
alertHighReport.setItemName(survAlertRecord.getItemName());
|
||||||
|
alertHighReport.setItemUnit(survAlertRecord.getSurvUnit());
|
||||||
|
alertHighReport.setExtremeValue(survAlertRecord.getSurvValue());
|
||||||
|
alertHighReport.setAlertCount(0);
|
||||||
|
}
|
||||||
|
alertHighReport.setAlertCount(alertHighReport.getAlertCount() + 1);
|
||||||
|
alertHighMap.put(survAlertRecord.getItemCode(),alertHighReport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MonitoringDataRichTextBuilder.MonitoringStats stats = new MonitoringDataRichTextBuilder.MonitoringStats();
|
||||||
|
stats.setTotalSamples(dataCounts.intValue());
|
||||||
|
stats.setIndicatorsCount(zhibiaoMap.size());
|
||||||
|
BigDecimal total = new BigDecimal(dataCounts);
|
||||||
|
BigDecimal abnormal = new BigDecimal(abnormalCount);
|
||||||
|
|
||||||
|
stats.setAbnormalRate(abnormal.divide(total, 3,RoundingMode.HALF_UP).doubleValue() * 100);
|
||||||
|
|
||||||
|
|
||||||
|
// 超上限
|
||||||
|
List<MonitoringDataRichTextBuilder.AbnormalItem> aboveList = new ArrayList<>();
|
||||||
|
|
||||||
|
if(!alertHighMap.isEmpty()){
|
||||||
|
for (String s : alertHighMap.keySet()) {
|
||||||
|
AlertReport alertReport = alertHighMap.get(s);
|
||||||
|
|
||||||
|
MonitoringDataRichTextBuilder.AbnormalItem tempItem = new MonitoringDataRichTextBuilder.AbnormalItem();
|
||||||
|
tempItem.setIndicatorName(alertReport.getItemName());
|
||||||
|
tempItem.setCount(alertReport.getAlertCount());
|
||||||
|
tempItem.setExtremeValue("最高 " + alertReport.getExtremeValue());
|
||||||
|
aboveList.add(tempItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.setAboveUpperLimit(aboveList);
|
||||||
|
|
||||||
|
// 低于下限
|
||||||
|
List<MonitoringDataRichTextBuilder.AbnormalItem> belowList = new ArrayList<>();
|
||||||
|
if(!alertLowMap.isEmpty()){
|
||||||
|
for (String s : alertLowMap.keySet()) {
|
||||||
|
AlertReport alertReport = alertLowMap.get(s);
|
||||||
|
|
||||||
|
MonitoringDataRichTextBuilder.AbnormalItem tempItem = new MonitoringDataRichTextBuilder.AbnormalItem();
|
||||||
|
tempItem.setIndicatorName(alertReport.getItemName());
|
||||||
|
tempItem.setCount(alertReport.getAlertCount());
|
||||||
|
tempItem.setExtremeValue("最低 " + alertReport.getExtremeValue());
|
||||||
|
belowList.add(tempItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stats.setBelowLowerLimit(belowList);
|
||||||
|
|
||||||
|
|
||||||
|
// 正常指标
|
||||||
|
List<String> allItems = new ArrayList<>(zhibiaoMap.keySet());
|
||||||
|
allItems.removeAll(unnormalList);
|
||||||
|
List<String> normalItems = new ArrayList<>();
|
||||||
|
if(!allItems.isEmpty()){
|
||||||
|
for (String allItem : allItems) {
|
||||||
|
String zhibiao = zhibiaoMap.get(allItem);
|
||||||
|
normalItems.add(zhibiao);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stats.setNormalIndicators(normalItems);
|
||||||
|
|
||||||
|
return MonitoringDataRichTextBuilder.buildRichText(stats);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,36 @@
|
||||||
package org.jeecg.modules.appmana.service.impl;
|
package org.jeecg.modules.appmana.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jeecg.common.constant.IotConstants;
|
||||||
|
import org.jeecg.common.constant.enums.PollutionEnum;
|
||||||
|
import org.jeecg.common.dto.AlertSummaryDTO;
|
||||||
|
import org.jeecg.common.entity.ScEquZhibiao;
|
||||||
import org.jeecg.common.entity.SurvAlertRecord;
|
import org.jeecg.common.entity.SurvAlertRecord;
|
||||||
|
import org.jeecg.common.entity.SurvDeviceDeploy;
|
||||||
|
import org.jeecg.common.util.DateRangeUtil;
|
||||||
|
import org.jeecg.common.util.TimeIntervalUtils;
|
||||||
|
import org.jeecg.common.vo.iot.common.SurvItemInfo;
|
||||||
|
import org.jeecg.common.vo.statistic.AlertSummaryVo;
|
||||||
|
import org.jeecg.common.vo.statistic.AlertSummayDetail;
|
||||||
|
import org.jeecg.common.vo.statistic.CommonDateListResult;
|
||||||
import org.jeecg.modules.appmana.mapper.SurvAlertRecordMapper;
|
import org.jeecg.modules.appmana.mapper.SurvAlertRecordMapper;
|
||||||
import org.jeecg.modules.appmana.service.ISurvAlertRecordService;
|
import org.jeecg.modules.appmana.service.ISurvAlertRecordService;
|
||||||
|
import org.jeecg.modules.appmana.service.ISurvDeviceDeployService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.temporal.TemporalAdjusters;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: surv_alert_record
|
* @Description: surv_alert_record
|
||||||
|
|
@ -16,8 +39,13 @@ import java.util.List;
|
||||||
* @Version: V1.0
|
* @Version: V1.0
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class SurvAlertRecordServiceImpl extends ServiceImpl<SurvAlertRecordMapper, SurvAlertRecord> implements ISurvAlertRecordService {
|
public class SurvAlertRecordServiceImpl extends ServiceImpl<SurvAlertRecordMapper, SurvAlertRecord> implements ISurvAlertRecordService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private ISurvDeviceDeployService deployService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPage<SurvAlertRecord> pages(IPage<SurvAlertRecord> page, SurvAlertRecord survAlertRecord) {
|
public IPage<SurvAlertRecord> pages(IPage<SurvAlertRecord> page, SurvAlertRecord survAlertRecord) {
|
||||||
return baseMapper.pages(page,survAlertRecord);
|
return baseMapper.pages(page,survAlertRecord);
|
||||||
|
|
@ -27,4 +55,130 @@ public class SurvAlertRecordServiceImpl extends ServiceImpl<SurvAlertRecordMappe
|
||||||
public IPage<SurvAlertRecord> pageByDevice(IPage<SurvAlertRecord> page, List<String> deviceList, String yearStr) {
|
public IPage<SurvAlertRecord> pageByDevice(IPage<SurvAlertRecord> page, List<String> deviceList, String yearStr) {
|
||||||
return baseMapper.pageByDevice(page,deviceList,yearStr);
|
return baseMapper.pageByDevice(page,deviceList,yearStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AlertSummaryVo getSummary(AlertSummaryDTO alertSummaryDTO) {
|
||||||
|
Assert.notNull(alertSummaryDTO,"传入格式错误");
|
||||||
|
String tenantId = alertSummaryDTO.getTenantId();
|
||||||
|
SurvDeviceDeploy deploy = deployService.getDeployZhibiao(alertSummaryDTO.getDeployId(),tenantId);
|
||||||
|
Assert.notNull(deploy,"设备无效");
|
||||||
|
AlertSummaryVo alertSummaryVo = new AlertSummaryVo();
|
||||||
|
List<SurvItemInfo> survItemInfos = new ArrayList<>();
|
||||||
|
// step 1 所有监测项字典信息
|
||||||
|
if(deploy.getZhibiaos()!=null && !deploy.getZhibiaos().isEmpty()){
|
||||||
|
for (ScEquZhibiao zhibiao : deploy.getZhibiaos()) {
|
||||||
|
SurvItemInfo survItemInfo = new SurvItemInfo();
|
||||||
|
PollutionEnum pollutionEnum = PollutionEnum.catchPollution(zhibiao.getEntityField());
|
||||||
|
survItemInfo.setItemName(zhibiao.getName());
|
||||||
|
survItemInfo.setColor(pollutionEnum.getColor());
|
||||||
|
survItemInfo.setHighVal(zhibiao.getValHeight()!=null ?zhibiao.getValHeight()+"":null);
|
||||||
|
survItemInfo.setLowVal(zhibiao.getValLow()!=null?zhibiao.getValLow()+"":null);
|
||||||
|
survItemInfo.setUnit(zhibiao.getNuit());
|
||||||
|
survItemInfo.setEntity(zhibiao.getEntityField());
|
||||||
|
survItemInfo.setPid(zhibiao.getEleKey());
|
||||||
|
survItemInfos.add(survItemInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alertSummaryVo.setItemList(survItemInfos);
|
||||||
|
Map<String, SurvItemInfo> itemMap = survItemInfos.stream()
|
||||||
|
.collect(Collectors.toMap(SurvItemInfo::getEntity, itemss -> itemss));
|
||||||
|
alertSummaryVo.setItemInfo(itemMap);
|
||||||
|
|
||||||
|
//step 2:获取每5分钟 的数据
|
||||||
|
|
||||||
|
|
||||||
|
String startTime = alertSummaryDTO.getStartTime();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LocalDateTime startDateTime = null;
|
||||||
|
LocalDateTime endDateTime = null;
|
||||||
|
boolean isToday = false;
|
||||||
|
LocalDateTime nowTime = LocalDateTime.now();
|
||||||
|
LocalDate nowDate = nowTime.toLocalDate();
|
||||||
|
if(StringUtils.isNotBlank(startTime)){
|
||||||
|
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
if(IotConstants.day_hours.equals(alertSummaryDTO.getSummaryMode())){
|
||||||
|
|
||||||
|
startDateTime = LocalDateTime.of(LocalDate.parse(startTime,dtf), LocalTime.MIN);
|
||||||
|
endDateTime = LocalDateTime.of(LocalDate.parse(startTime,dtf), LocalTime.MAX).withNano(999999000);
|
||||||
|
//检查是否传入的今天
|
||||||
|
if(nowDate.equals(startDateTime.toLocalDate())){
|
||||||
|
isToday = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(IotConstants.month_days.equals(alertSummaryDTO.getSummaryMode())){
|
||||||
|
startDateTime = LocalDateTime.of(LocalDate.parse(startTime + "-01",dtf), LocalTime.MIN);
|
||||||
|
endDateTime = LocalDateTime.of(startDateTime.toLocalDate().with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX).withNano(999999000);
|
||||||
|
//检查是否传入的今天
|
||||||
|
if(nowDate.equals(startDateTime.toLocalDate())){
|
||||||
|
isToday = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(IotConstants.year_months.equals(alertSummaryDTO.getSummaryMode())){
|
||||||
|
startDateTime = LocalDateTime.of(LocalDate.parse(startTime+"-01-01",dtf), LocalTime.MIN);
|
||||||
|
endDateTime = LocalDateTime.of(LocalDate.parse(startTime+"-12-31",dtf), LocalTime.MAX).withNano(999999000);
|
||||||
|
//检查是否传入的今天
|
||||||
|
if(nowDate.equals(startDateTime.toLocalDate())){
|
||||||
|
isToday = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
isToday = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isToday){//如果查询的是今天,只查询到当前时间
|
||||||
|
if(IotConstants.day_hours.equals(alertSummaryDTO.getSummaryMode())){
|
||||||
|
startDateTime = nowTime.minusDays(1);
|
||||||
|
endDateTime = nowTime.withNano(999999000);
|
||||||
|
}
|
||||||
|
else if(IotConstants.month_days.equals(alertSummaryDTO.getSummaryMode())){
|
||||||
|
startDateTime = LocalDateTime.of(nowDate.getYear(),nowDate.getMonthValue(),1,0,0,0,999999000);
|
||||||
|
endDateTime = LocalDateTime.of(nowDate.getYear(),nowDate.getMonthValue(),nowDate.getDayOfMonth(),23,59,59,0);
|
||||||
|
}
|
||||||
|
else if(IotConstants.year_months.equals(alertSummaryDTO.getSummaryMode())){
|
||||||
|
startDateTime = LocalDateTime.of(nowDate.getYear(),1,1,0,0,0,999999000);
|
||||||
|
endDateTime = LocalDateTime.of(nowDate.getYear(),12,31,23,59,59,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<String> showTime = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
Map<String,List<String>> dataMap = new HashMap<>();
|
||||||
|
if(!survItemInfos.isEmpty()){
|
||||||
|
for (SurvItemInfo survItemInfo : survItemInfos) {
|
||||||
|
List<AlertSummayDetail> records = new ArrayList<>();
|
||||||
|
if(IotConstants.day_hours.equals(alertSummaryDTO.getSummaryMode())){
|
||||||
|
CommonDateListResult commonDateListResult = TimeIntervalUtils.generate5MinuteIntervals(startDateTime,endDateTime);
|
||||||
|
showTime = commonDateListResult.getShowList();
|
||||||
|
records = baseMapper.getSpotCheckData(alertSummaryDTO.getDeployId(),survItemInfo.getEntity(),commonDateListResult.getQueryList(),startDateTime,endDateTime);
|
||||||
|
}
|
||||||
|
else if(IotConstants.month_days.equals(alertSummaryDTO.getSummaryMode())){
|
||||||
|
List<String> dateList = DateRangeUtil.getDateListBetween(startDateTime,endDateTime);
|
||||||
|
showTime = DateRangeUtil.convertDateFormatStream(dateList,"yyyy-MM-dd","MM月dd日");
|
||||||
|
records = baseMapper.getDailyMaxSpotCheckData(dateList,startDateTime,endDateTime,alertSummaryDTO.getDeployId(),survItemInfo.getEntity());
|
||||||
|
}
|
||||||
|
else if(IotConstants.year_months.equals(alertSummaryDTO.getSummaryMode())){
|
||||||
|
List<String> dateList = DateRangeUtil.getMonthListBetween(startDateTime,endDateTime);
|
||||||
|
|
||||||
|
records = baseMapper.getMonthMaxSpotCheckData(dateList,startDateTime,endDateTime,alertSummaryDTO.getDeployId(),survItemInfo.getEntity());
|
||||||
|
List<String> monthList = new ArrayList<>();
|
||||||
|
dateList.forEach(date -> {
|
||||||
|
date = date+"-01";
|
||||||
|
monthList.add(date);
|
||||||
|
});
|
||||||
|
showTime = DateRangeUtil.convertDateFormatStream(monthList,"yyyy-MM-dd","MM月");
|
||||||
|
}
|
||||||
|
//组装map
|
||||||
|
if(!records.isEmpty()){
|
||||||
|
List<String> dataList = records.stream().map(AlertSummayDetail::getSurvValue).collect(Collectors.toList());
|
||||||
|
dataMap.put(survItemInfo.getEntity(),dataList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alertSummaryVo.setTimeList(showTime);
|
||||||
|
alertSummaryVo.setDataMap(dataMap);
|
||||||
|
return alertSummaryVo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -631,4 +631,9 @@ public class SurvDeviceDeployServiceImpl extends ServiceImpl<SurvDeviceDeployMap
|
||||||
public SurvDeviceDeploy getDeviceById(String deployId, String tenantId) {
|
public SurvDeviceDeploy getDeviceById(String deployId, String tenantId) {
|
||||||
return baseMapper.getDeviceById(deployId,tenantId);
|
return baseMapper.getDeviceById(deployId,tenantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SurvDeviceDeploy getDeployZhibiao(String deployId, String tenantId) {
|
||||||
|
return baseMapper.getDeployZhibiao(deployId,tenantId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,196 @@
|
||||||
|
package org.jeecg.modules.appmana.utils;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MonitoringDataRichTextBuilder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监测数据统计信息
|
||||||
|
*/
|
||||||
|
public static class MonitoringStats {
|
||||||
|
/**
|
||||||
|
* 总样本数
|
||||||
|
*/
|
||||||
|
private int totalSamples;
|
||||||
|
/**
|
||||||
|
* 指标总数
|
||||||
|
*/
|
||||||
|
private int indicatorsCount;
|
||||||
|
/**
|
||||||
|
* 异常指标占比
|
||||||
|
*/
|
||||||
|
private double abnormalRate;
|
||||||
|
|
||||||
|
private List<AbnormalItem> aboveUpperLimit;
|
||||||
|
private List<AbnormalItem> belowLowerLimit;
|
||||||
|
private List<String> normalIndicators;
|
||||||
|
|
||||||
|
// getter/setter
|
||||||
|
public int getTotalSamples() { return totalSamples; }
|
||||||
|
public void setTotalSamples(int totalSamples) { this.totalSamples = totalSamples; }
|
||||||
|
public int getIndicatorsCount() { return indicatorsCount; }
|
||||||
|
public void setIndicatorsCount(int indicatorsCount) { this.indicatorsCount = indicatorsCount; }
|
||||||
|
public double getAbnormalRate() { return abnormalRate; }
|
||||||
|
public void setAbnormalRate(double abnormalRate) { this.abnormalRate = abnormalRate; }
|
||||||
|
public List<AbnormalItem> getAboveUpperLimit() { return aboveUpperLimit; }
|
||||||
|
public void setAboveUpperLimit(List<AbnormalItem> aboveUpperLimit) { this.aboveUpperLimit = aboveUpperLimit; }
|
||||||
|
public List<AbnormalItem> getBelowLowerLimit() { return belowLowerLimit; }
|
||||||
|
public void setBelowLowerLimit(List<AbnormalItem> belowLowerLimit) { this.belowLowerLimit = belowLowerLimit; }
|
||||||
|
public List<String> getNormalIndicators() { return normalIndicators; }
|
||||||
|
public void setNormalIndicators(List<String> normalIndicators) { this.normalIndicators = normalIndicators; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常项
|
||||||
|
*/
|
||||||
|
public static class AbnormalItem {
|
||||||
|
/**
|
||||||
|
* 异常指标名称
|
||||||
|
*/
|
||||||
|
private String indicatorName;
|
||||||
|
/**
|
||||||
|
* 异常指标数量
|
||||||
|
*/
|
||||||
|
private int count;
|
||||||
|
/**
|
||||||
|
* 异常指标异常值
|
||||||
|
*/
|
||||||
|
private String extremeValue;
|
||||||
|
|
||||||
|
public String getIndicatorName() { return indicatorName; }
|
||||||
|
public void setIndicatorName(String indicatorName) { this.indicatorName = indicatorName; }
|
||||||
|
public int getCount() { return count; }
|
||||||
|
public void setCount(int count) { this.count = count; }
|
||||||
|
public String getExtremeValue() { return extremeValue; }
|
||||||
|
public void setExtremeValue(String extremeValue) { this.extremeValue = extremeValue; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成富文本HTML内容(无Emoji,使用通用符号)
|
||||||
|
*/
|
||||||
|
public static String buildRichText(MonitoringStats stats) {
|
||||||
|
StringBuilder html = new StringBuilder();
|
||||||
|
|
||||||
|
// 1. 标题 - 监测数据概况
|
||||||
|
html.append("<div style='font-size:18px;font-weight:bold;color:#333;margin-bottom:12px;'>")
|
||||||
|
.append("【监测数据概况】")
|
||||||
|
.append("</div>");
|
||||||
|
|
||||||
|
// 2. 摘要统计信息
|
||||||
|
html.append("<div style='background:#f5f7fa;padding:10px 14px;border-radius:6px;margin-bottom:14px;'>")
|
||||||
|
.append("<span style='margin-right:20px;'>共采集 <strong style='color:#1890ff;'>")
|
||||||
|
.append(stats.totalSamples)
|
||||||
|
.append("</strong> 次</span>")
|
||||||
|
.append("<span style='margin-right:20px;'>覆盖 <strong style='color:#1890ff;'>")
|
||||||
|
.append(stats.indicatorsCount)
|
||||||
|
.append("</strong> 项指标</span>")
|
||||||
|
.append("<span>异常率 <strong style='color:")
|
||||||
|
.append(stats.abnormalRate > 5 ? "#f5222d" : "#faad14")
|
||||||
|
.append(";'>")
|
||||||
|
.append(String.format("%.1f", stats.abnormalRate))
|
||||||
|
.append("%</strong></span>")
|
||||||
|
.append("</div>");
|
||||||
|
|
||||||
|
// 3. 超上限部分(使用 [↑] 符号)
|
||||||
|
if (stats.aboveUpperLimit != null && !stats.aboveUpperLimit.isEmpty()) {
|
||||||
|
html.append("<div style='margin-bottom:8px;'>")
|
||||||
|
.append("<span style='font-weight:bold;color:#cf1322;'>[↑] 超上限:</span>")
|
||||||
|
.append("<span style='font-size:14px;'>");
|
||||||
|
|
||||||
|
List<String> items = new ArrayList<>();
|
||||||
|
for (AbnormalItem item : stats.aboveUpperLimit) {
|
||||||
|
String text = item.getIndicatorName() + ":<span style='color:#cf1322;font-weight:bold;'>"
|
||||||
|
+ item.getCount() + " 次</span>";
|
||||||
|
if (item.getExtremeValue() != null && !item.getExtremeValue().isEmpty()) {
|
||||||
|
text += "(" + item.getExtremeValue() + ")";
|
||||||
|
}
|
||||||
|
items.add(text);
|
||||||
|
}
|
||||||
|
html.append(String.join(" | ", items));
|
||||||
|
html.append("</span></div>");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 低于下限部分(使用 [↓] 符号)
|
||||||
|
if (stats.belowLowerLimit != null && !stats.belowLowerLimit.isEmpty()) {
|
||||||
|
html.append("<div style='margin-bottom:8px;'>")
|
||||||
|
.append("<span style='font-weight:bold;color:#389e0d;'>[↓] 低于下限:</span>")
|
||||||
|
.append("<span style='font-size:14px;'>");
|
||||||
|
|
||||||
|
List<String> items = new ArrayList<>();
|
||||||
|
for (AbnormalItem item : stats.belowLowerLimit) {
|
||||||
|
String text = item.getIndicatorName() + ":<span style='color:#389e0d;font-weight:bold;'>"
|
||||||
|
+ item.getCount() + " 次</span>";
|
||||||
|
if (item.getExtremeValue() != null && !item.getExtremeValue().isEmpty()) {
|
||||||
|
text += "(" + item.getExtremeValue() + ")";
|
||||||
|
}
|
||||||
|
items.add(text);
|
||||||
|
}
|
||||||
|
html.append(String.join(" | ", items));
|
||||||
|
html.append("</span></div>");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 正常指标(使用 [√] 符号)
|
||||||
|
if (stats.normalIndicators != null && !stats.normalIndicators.isEmpty()) {
|
||||||
|
html.append("<div style='margin-top:8px;padding-top:8px;border-top:1px dashed #e8e8e8;'>")
|
||||||
|
.append("<span style='font-weight:bold;color:#52c41a;'>[√] 正常指标:</span>")
|
||||||
|
.append("<span style='font-size:14px;color:#595959;'>")
|
||||||
|
.append(String.join("、", stats.normalIndicators))
|
||||||
|
.append("</span>")
|
||||||
|
.append("</div>");
|
||||||
|
}
|
||||||
|
|
||||||
|
return html.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从原始数据构建(示例)
|
||||||
|
*/
|
||||||
|
public static String buildFromRawText() {
|
||||||
|
MonitoringStats stats = new MonitoringStats();
|
||||||
|
stats.setTotalSamples(1284);
|
||||||
|
stats.setIndicatorsCount(6);
|
||||||
|
stats.setAbnormalRate(3.2);
|
||||||
|
|
||||||
|
// 超上限
|
||||||
|
List<AbnormalItem> aboveList = new ArrayList<>();
|
||||||
|
AbnormalItem tempItem = new AbnormalItem();
|
||||||
|
tempItem.setIndicatorName("温度");
|
||||||
|
tempItem.setCount(23);
|
||||||
|
tempItem.setExtremeValue("最高 42.6℃");
|
||||||
|
aboveList.add(tempItem);
|
||||||
|
|
||||||
|
AbnormalItem pressureItem = new AbnormalItem();
|
||||||
|
pressureItem.setIndicatorName("气压");
|
||||||
|
pressureItem.setCount(5);
|
||||||
|
pressureItem.setExtremeValue(null);
|
||||||
|
aboveList.add(pressureItem);
|
||||||
|
stats.setAboveUpperLimit(aboveList);
|
||||||
|
|
||||||
|
// 低于下限
|
||||||
|
List<AbnormalItem> belowList = new ArrayList<>();
|
||||||
|
AbnormalItem humidityItem = new AbnormalItem();
|
||||||
|
humidityItem.setIndicatorName("湿度");
|
||||||
|
humidityItem.setCount(8);
|
||||||
|
humidityItem.setExtremeValue("最低 18.3%");
|
||||||
|
belowList.add(humidityItem);
|
||||||
|
stats.setBelowLowerLimit(belowList);
|
||||||
|
|
||||||
|
// 正常指标
|
||||||
|
List<String> normalList = new ArrayList<>();
|
||||||
|
normalList.add("PM2.5");
|
||||||
|
normalList.add("CO₂");
|
||||||
|
normalList.add("噪声");
|
||||||
|
stats.setNormalIndicators(normalList);
|
||||||
|
|
||||||
|
return buildRichText(stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 主方法测试 ==========
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String richText = buildFromRawText();
|
||||||
|
System.out.println("生成的富文本HTML内容:");
|
||||||
|
System.out.println("================================");
|
||||||
|
System.out.println(richText);
|
||||||
|
System.out.println("================================");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package org.jeecg.common.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AlertSummaryDTO {
|
||||||
|
@ApiModelProperty("设备ID")
|
||||||
|
private String deployId;
|
||||||
|
|
||||||
|
@ApiModelProperty("统计模式")
|
||||||
|
private String summaryMode;
|
||||||
|
|
||||||
|
@ApiModelProperty("开始时间")
|
||||||
|
private String startTime;
|
||||||
|
|
||||||
|
@ApiModelProperty("结束时间")
|
||||||
|
private String endTime;
|
||||||
|
|
||||||
|
@ApiModelProperty("租户ID")
|
||||||
|
private String tenantId;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,549 @@
|
||||||
|
package org.jeecg.common.util;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.YearMonth;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期范围工具类 - 获取两个日期之间的所有日期和月份
|
||||||
|
*/
|
||||||
|
public class DateRangeUtil {
|
||||||
|
|
||||||
|
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM");
|
||||||
|
|
||||||
|
// ==================== 日期相关方法 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有日期(包含开始和结束日期)
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间
|
||||||
|
* @return 日期字符串列表,格式 yyyy-MM-dd,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getDateListBetween(LocalDateTime start, LocalDateTime end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate startDate = start.toLocalDate();
|
||||||
|
LocalDate endDate = end.toLocalDate();
|
||||||
|
|
||||||
|
// 如果开始日期在结束日期之后,交换位置
|
||||||
|
if (startDate.isAfter(endDate)) {
|
||||||
|
LocalDate temp = startDate;
|
||||||
|
startDate = endDate;
|
||||||
|
endDate = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getDateListBetween(startDate, endDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有日期(包含开始和结束日期)
|
||||||
|
* @param start 开始日期
|
||||||
|
* @param end 结束日期
|
||||||
|
* @return 日期字符串列表,格式 yyyy-MM-dd,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getDateListBetween(LocalDate start, LocalDate end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果开始日期在结束日期之后,交换位置
|
||||||
|
if (start.isAfter(end)) {
|
||||||
|
LocalDate temp = start;
|
||||||
|
start = end;
|
||||||
|
end = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> dateList = new ArrayList<>();
|
||||||
|
LocalDate current = start;
|
||||||
|
|
||||||
|
while (!current.isAfter(end)) {
|
||||||
|
dateList.add(current.format(DATE_FORMATTER));
|
||||||
|
current = current.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有日期(包含开始和结束日期)
|
||||||
|
* 使用 Stream 流式处理
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间
|
||||||
|
* @return 日期字符串列表,格式 yyyy-MM-dd,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getDateListBetweenStream(LocalDateTime start, LocalDateTime end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate startDate = start.toLocalDate();
|
||||||
|
LocalDate endDate = end.toLocalDate();
|
||||||
|
|
||||||
|
// 如果开始日期在结束日期之后,交换位置
|
||||||
|
if (startDate.isAfter(endDate)) {
|
||||||
|
LocalDate temp = startDate;
|
||||||
|
startDate = endDate;
|
||||||
|
endDate = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Stream.iterate(startDate, date -> date.plusDays(1))
|
||||||
|
.limit(startDate.until(endDate).getDays() + 1)
|
||||||
|
.map(date -> date.format(DATE_FORMATTER))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有日期(不包含结束日期)
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间(不包含)
|
||||||
|
* @return 日期字符串列表,格式 yyyy-MM-dd,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getDateListBetweenExclusiveEnd(LocalDateTime start, LocalDateTime end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate startDate = start.toLocalDate();
|
||||||
|
LocalDate endDate = end.toLocalDate();
|
||||||
|
|
||||||
|
// 如果开始日期在结束日期之后,交换位置
|
||||||
|
if (startDate.isAfter(endDate)) {
|
||||||
|
LocalDate temp = startDate;
|
||||||
|
startDate = endDate;
|
||||||
|
endDate = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> dateList = new ArrayList<>();
|
||||||
|
LocalDate current = startDate;
|
||||||
|
|
||||||
|
while (current.isBefore(endDate)) {
|
||||||
|
dateList.add(current.format(DATE_FORMATTER));
|
||||||
|
current = current.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有日期(不包含开始日期)
|
||||||
|
* @param start 开始时间(不包含)
|
||||||
|
* @param end 结束时间
|
||||||
|
* @return 日期字符串列表,格式 yyyy-MM-dd,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getDateListBetweenExclusiveStart(LocalDateTime start, LocalDateTime end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate startDate = start.toLocalDate();
|
||||||
|
LocalDate endDate = end.toLocalDate();
|
||||||
|
|
||||||
|
// 如果开始日期在结束日期之后,交换位置
|
||||||
|
if (startDate.isAfter(endDate)) {
|
||||||
|
LocalDate temp = startDate;
|
||||||
|
startDate = endDate;
|
||||||
|
endDate = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> dateList = new ArrayList<>();
|
||||||
|
LocalDate current = startDate.plusDays(1);
|
||||||
|
|
||||||
|
while (!current.isAfter(endDate)) {
|
||||||
|
dateList.add(current.format(DATE_FORMATTER));
|
||||||
|
current = current.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有日期(包含开始和结束日期),返回 LocalDate 对象列表
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间
|
||||||
|
* @return LocalDate 列表,正序排列
|
||||||
|
*/
|
||||||
|
public static List<LocalDate> getLocalDateListBetween(LocalDateTime start, LocalDateTime end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate startDate = start.toLocalDate();
|
||||||
|
LocalDate endDate = end.toLocalDate();
|
||||||
|
|
||||||
|
// 如果开始日期在结束日期之后,交换位置
|
||||||
|
if (startDate.isAfter(endDate)) {
|
||||||
|
LocalDate temp = startDate;
|
||||||
|
startDate = endDate;
|
||||||
|
endDate = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<LocalDate> dateList = new ArrayList<>();
|
||||||
|
LocalDate current = startDate;
|
||||||
|
|
||||||
|
while (!current.isAfter(endDate)) {
|
||||||
|
dateList.add(current);
|
||||||
|
current = current.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有日期(包含开始和结束日期)
|
||||||
|
* 使用自定义日期格式
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间
|
||||||
|
* @param pattern 日期格式,如 "yyyy/MM/dd"
|
||||||
|
* @return 日期字符串列表,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getDateListBetween(LocalDateTime start, LocalDateTime end, String pattern) {
|
||||||
|
if (start == null || end == null || pattern == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||||
|
LocalDate startDate = start.toLocalDate();
|
||||||
|
LocalDate endDate = end.toLocalDate();
|
||||||
|
|
||||||
|
// 如果开始日期在结束日期之后,交换位置
|
||||||
|
if (startDate.isAfter(endDate)) {
|
||||||
|
LocalDate temp = startDate;
|
||||||
|
startDate = endDate;
|
||||||
|
endDate = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> dateList = new ArrayList<>();
|
||||||
|
LocalDate current = startDate;
|
||||||
|
|
||||||
|
while (!current.isAfter(endDate)) {
|
||||||
|
dateList.add(current.format(formatter));
|
||||||
|
current = current.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 月份相关方法(新增) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有月份(包含开始和结束月份)
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间
|
||||||
|
* @return 月份字符串列表,格式 yyyy-MM,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getMonthListBetween(LocalDateTime start, LocalDateTime end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
YearMonth startMonth = YearMonth.from(start);
|
||||||
|
YearMonth endMonth = YearMonth.from(end);
|
||||||
|
|
||||||
|
// 如果开始月份在结束月份之后,交换位置
|
||||||
|
if (startMonth.isAfter(endMonth)) {
|
||||||
|
YearMonth temp = startMonth;
|
||||||
|
startMonth = endMonth;
|
||||||
|
endMonth = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> monthList = new ArrayList<>();
|
||||||
|
YearMonth current = startMonth;
|
||||||
|
|
||||||
|
while (!current.isAfter(endMonth)) {
|
||||||
|
monthList.add(current.format(MONTH_FORMATTER));
|
||||||
|
current = current.plusMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return monthList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有月份(包含开始和结束月份)
|
||||||
|
* 使用 Stream 流式处理
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间
|
||||||
|
* @return 月份字符串列表,格式 yyyy-MM,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getMonthListBetweenStream(LocalDateTime start, LocalDateTime end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
YearMonth startMonth = YearMonth.from(start);
|
||||||
|
YearMonth endMonth = YearMonth.from(end);
|
||||||
|
|
||||||
|
// 如果开始月份在结束月份之后,交换位置
|
||||||
|
if (startMonth.isAfter(endMonth)) {
|
||||||
|
YearMonth temp = startMonth;
|
||||||
|
startMonth = endMonth;
|
||||||
|
endMonth = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
long monthsBetween = startMonth.until(endMonth, java.time.temporal.ChronoUnit.MONTHS);
|
||||||
|
|
||||||
|
return Stream.iterate(startMonth, month -> month.plusMonths(1))
|
||||||
|
.limit(monthsBetween + 1)
|
||||||
|
.map(month -> month.format(MONTH_FORMATTER))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有月份(不包含结束月份)
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间(不包含)
|
||||||
|
* @return 月份字符串列表,格式 yyyy-MM,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getMonthListBetweenExclusiveEnd(LocalDateTime start, LocalDateTime end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
YearMonth startMonth = YearMonth.from(start);
|
||||||
|
YearMonth endMonth = YearMonth.from(end);
|
||||||
|
|
||||||
|
// 如果开始月份在结束月份之后,交换位置
|
||||||
|
if (startMonth.isAfter(endMonth)) {
|
||||||
|
YearMonth temp = startMonth;
|
||||||
|
startMonth = endMonth;
|
||||||
|
endMonth = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> monthList = new ArrayList<>();
|
||||||
|
YearMonth current = startMonth;
|
||||||
|
|
||||||
|
while (current.isBefore(endMonth)) {
|
||||||
|
monthList.add(current.format(MONTH_FORMATTER));
|
||||||
|
current = current.plusMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return monthList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有月份(不包含开始月份)
|
||||||
|
* @param start 开始时间(不包含)
|
||||||
|
* @param end 结束时间
|
||||||
|
* @return 月份字符串列表,格式 yyyy-MM,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getMonthListBetweenExclusiveStart(LocalDateTime start, LocalDateTime end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
YearMonth startMonth = YearMonth.from(start);
|
||||||
|
YearMonth endMonth = YearMonth.from(end);
|
||||||
|
|
||||||
|
// 如果开始月份在结束月份之后,交换位置
|
||||||
|
if (startMonth.isAfter(endMonth)) {
|
||||||
|
YearMonth temp = startMonth;
|
||||||
|
startMonth = endMonth;
|
||||||
|
endMonth = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> monthList = new ArrayList<>();
|
||||||
|
YearMonth current = startMonth.plusMonths(1);
|
||||||
|
|
||||||
|
while (!current.isAfter(endMonth)) {
|
||||||
|
monthList.add(current.format(MONTH_FORMATTER));
|
||||||
|
current = current.plusMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return monthList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有月份(包含开始和结束月份),返回 YearMonth 对象列表
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间
|
||||||
|
* @return YearMonth 列表,正序排列
|
||||||
|
*/
|
||||||
|
public static List<YearMonth> getYearMonthListBetween(LocalDateTime start, LocalDateTime end) {
|
||||||
|
if (start == null || end == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
YearMonth startMonth = YearMonth.from(start);
|
||||||
|
YearMonth endMonth = YearMonth.from(end);
|
||||||
|
|
||||||
|
// 如果开始月份在结束月份之后,交换位置
|
||||||
|
if (startMonth.isAfter(endMonth)) {
|
||||||
|
YearMonth temp = startMonth;
|
||||||
|
startMonth = endMonth;
|
||||||
|
endMonth = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<YearMonth> monthList = new ArrayList<>();
|
||||||
|
YearMonth current = startMonth;
|
||||||
|
|
||||||
|
while (!current.isAfter(endMonth)) {
|
||||||
|
monthList.add(current);
|
||||||
|
current = current.plusMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return monthList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有月份(包含开始和结束月份)
|
||||||
|
* 使用自定义月份格式
|
||||||
|
* @param start 开始时间
|
||||||
|
* @param end 结束时间
|
||||||
|
* @param pattern 月份格式,如 "yyyy年MM月"
|
||||||
|
* @return 月份字符串列表,正序排列
|
||||||
|
*/
|
||||||
|
public static List<String> getMonthListBetween(LocalDateTime start, LocalDateTime end, String pattern) {
|
||||||
|
if (start == null || end == null || pattern == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||||
|
YearMonth startMonth = YearMonth.from(start);
|
||||||
|
YearMonth endMonth = YearMonth.from(end);
|
||||||
|
|
||||||
|
// 如果开始月份在结束月份之后,交换位置
|
||||||
|
if (startMonth.isAfter(endMonth)) {
|
||||||
|
YearMonth temp = startMonth;
|
||||||
|
startMonth = endMonth;
|
||||||
|
endMonth = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> monthList = new ArrayList<>();
|
||||||
|
YearMonth current = startMonth;
|
||||||
|
|
||||||
|
while (!current.isAfter(endMonth)) {
|
||||||
|
monthList.add(current.format(formatter));
|
||||||
|
current = current.plusMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return monthList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量转换日期字符串格式
|
||||||
|
* @param dateList 日期字符串列表
|
||||||
|
* @param sourcePattern 源日期格式,如 "yyyy-MM-dd"
|
||||||
|
* @param targetPattern 目标日期格式,如 "yyyy/MM/dd"
|
||||||
|
* @return 转换后的日期字符串列表,保持原有顺序
|
||||||
|
*/
|
||||||
|
public static List<String> convertDateFormat(List<String> dateList, String sourcePattern, String targetPattern) {
|
||||||
|
if (dateList == null || dateList.isEmpty() || sourcePattern == null || targetPattern == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern(sourcePattern);
|
||||||
|
DateTimeFormatter targetFormatter = DateTimeFormatter.ofPattern(targetPattern);
|
||||||
|
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
for (String dateStr : dateList) {
|
||||||
|
try {
|
||||||
|
// 先解析为 LocalDate,再格式化为目标格式
|
||||||
|
LocalDate date = LocalDate.parse(dateStr, sourceFormatter);
|
||||||
|
result.add(date.format(targetFormatter));
|
||||||
|
} catch (DateTimeParseException e) {
|
||||||
|
// 如果解析失败,跳过该日期或保留原值
|
||||||
|
// 这里选择保留原值并打印警告
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println("日期格式转换失败: " + dateStr + ", 格式: " + sourcePattern);
|
||||||
|
result.add(dateStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量转换日期字符串格式(使用 Stream 流式处理)
|
||||||
|
* @param dateList 日期字符串列表
|
||||||
|
* @param sourcePattern 源日期格式,如 "yyyy-MM-dd"
|
||||||
|
* @param targetPattern 目标日期格式,如 "yyyy/MM/dd"
|
||||||
|
* @return 转换后的日期字符串列表,保持原有顺序
|
||||||
|
*/
|
||||||
|
public static List<String> convertDateFormatStream(List<String> dateList, String sourcePattern, String targetPattern) {
|
||||||
|
if (dateList == null || dateList.isEmpty() || sourcePattern == null || targetPattern == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern(sourcePattern);
|
||||||
|
DateTimeFormatter targetFormatter = DateTimeFormatter.ofPattern(targetPattern);
|
||||||
|
|
||||||
|
return dateList.stream()
|
||||||
|
.map(dateStr -> {
|
||||||
|
try {
|
||||||
|
LocalDate date = LocalDate.parse(dateStr, sourceFormatter);
|
||||||
|
return date.format(targetFormatter);
|
||||||
|
} catch (DateTimeParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println("日期格式转换失败: " + dateStr + ", 格式: " + sourcePattern);
|
||||||
|
return dateStr;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==================== 使用示例 ====================
|
||||||
|
public static void main(String[] args) {
|
||||||
|
LocalDateTime start = LocalDateTime.of(2026, 1, 15, 10, 0, 0);
|
||||||
|
LocalDateTime end = LocalDateTime.of(2026, 7, 20, 18, 30, 0);
|
||||||
|
|
||||||
|
System.out.println("========== 获取所有日期 ==========");
|
||||||
|
System.out.println("开始时间: " + start);
|
||||||
|
System.out.println("结束时间: " + end);
|
||||||
|
|
||||||
|
List<String> dateList = getDateListBetween(start, end);
|
||||||
|
System.out.println("日期列表 (包含开始和结束):");
|
||||||
|
System.out.println("共 " + dateList.size() + " 天");
|
||||||
|
dateList.forEach(System.out::println);
|
||||||
|
|
||||||
|
System.out.println("\n========== 获取所有月份(新增功能) ==========");
|
||||||
|
List<String> monthList = getMonthListBetween(start, end);
|
||||||
|
System.out.println("月份列表 (包含开始和结束月份):");
|
||||||
|
System.out.println("共 " + monthList.size() + " 个月");
|
||||||
|
monthList.forEach(System.out::println);
|
||||||
|
|
||||||
|
System.out.println("\n========== 跨年月份测试 ==========");
|
||||||
|
LocalDateTime crossYearStart = LocalDateTime.of(2026, 11, 15, 0, 0, 0);
|
||||||
|
LocalDateTime crossYearEnd = LocalDateTime.of(2027, 3, 20, 0, 0, 0);
|
||||||
|
List<String> crossYearMonths = getMonthListBetween(crossYearStart, crossYearEnd);
|
||||||
|
System.out.println("跨年月份列表:");
|
||||||
|
crossYearMonths.forEach(System.out::println);
|
||||||
|
|
||||||
|
System.out.println("\n========== 不包含结束月份 ==========");
|
||||||
|
List<String> exclusiveEndMonths = getMonthListBetweenExclusiveEnd(start, end);
|
||||||
|
System.out.println("月份列表 (不包含结束月份):");
|
||||||
|
exclusiveEndMonths.forEach(System.out::println);
|
||||||
|
|
||||||
|
System.out.println("\n========== 不包含开始月份 ==========");
|
||||||
|
List<String> exclusiveStartMonths = getMonthListBetweenExclusiveStart(start, end);
|
||||||
|
System.out.println("月份列表 (不包含开始月份):");
|
||||||
|
exclusiveStartMonths.forEach(System.out::println);
|
||||||
|
|
||||||
|
System.out.println("\n========== 使用 Stream 方式 ==========");
|
||||||
|
List<String> streamMonths = getMonthListBetweenStream(start, end);
|
||||||
|
streamMonths.forEach(System.out::println);
|
||||||
|
|
||||||
|
System.out.println("\n========== 返回 YearMonth 对象 ==========");
|
||||||
|
List<YearMonth> yearMonthList = getYearMonthListBetween(start, end);
|
||||||
|
yearMonthList.forEach(System.out::println);
|
||||||
|
|
||||||
|
System.out.println("\n========== 自定义月份格式 ==========");
|
||||||
|
List<String> customFormatMonths = getMonthListBetween(start, end, "yyyy年MM月");
|
||||||
|
customFormatMonths.forEach(System.out::println);
|
||||||
|
|
||||||
|
System.out.println("\n========== 开始日期大于结束日期(自动交换) ==========");
|
||||||
|
LocalDateTime startLater = LocalDateTime.of(2026, 7, 20, 0, 0, 0);
|
||||||
|
LocalDateTime endEarlier = LocalDateTime.of(2026, 1, 15, 0, 0, 0);
|
||||||
|
List<String> swappedMonths = getMonthListBetween(startLater, endEarlier);
|
||||||
|
System.out.println("自动交换后的月份列表:");
|
||||||
|
swappedMonths.forEach(System.out::println);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
package org.jeecg.common.util;
|
||||||
|
|
||||||
|
import java.time.DayOfWeek;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.temporal.TemporalAdjusters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期时间工具类 - 用于获取本周、本月、本年的时间范围
|
||||||
|
*/
|
||||||
|
public class DateTimeRangeUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取本周的开始时间(周一 00:00:00)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getWeekStart() {
|
||||||
|
LocalDate monday = LocalDate.now().with(DayOfWeek.MONDAY);
|
||||||
|
return LocalDateTime.of(monday, LocalTime.MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取本周的结束时间(周日 23:59:59)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getWeekEnd() {
|
||||||
|
LocalDate sunday = LocalDate.now().with(DayOfWeek.SUNDAY);
|
||||||
|
return LocalDateTime.of(sunday, LocalTime.MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取本月的开始时间(1号 00:00:00)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getMonthStart() {
|
||||||
|
LocalDate firstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
|
||||||
|
return LocalDateTime.of(firstDay, LocalTime.MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取本月的结束时间(最后一天 23:59:59)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getMonthEnd() {
|
||||||
|
LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
|
||||||
|
return LocalDateTime.of(lastDay, LocalTime.MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取本年的开始时间(1月1日 00:00:00)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getYearStart() {
|
||||||
|
LocalDate firstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfYear());
|
||||||
|
return LocalDateTime.of(firstDay, LocalTime.MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取本年的结束时间(12月31日 23:59:59)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getYearEnd() {
|
||||||
|
LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfYear());
|
||||||
|
return LocalDateTime.of(lastDay, LocalTime.MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 指定日期时间的扩展方法 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期所在周的开始时间(周一 00:00:00)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getWeekStart(LocalDateTime dateTime) {
|
||||||
|
LocalDate monday = dateTime.toLocalDate().with(DayOfWeek.MONDAY);
|
||||||
|
return LocalDateTime.of(monday, LocalTime.MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期所在周的结束时间(周日 23:59:59)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getWeekEnd(LocalDateTime dateTime) {
|
||||||
|
LocalDate sunday = dateTime.toLocalDate().with(DayOfWeek.SUNDAY);
|
||||||
|
return LocalDateTime.of(sunday, LocalTime.MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期所在月的开始时间(1号 00:00:00)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getMonthStart(LocalDateTime dateTime) {
|
||||||
|
LocalDate firstDay = dateTime.toLocalDate().with(TemporalAdjusters.firstDayOfMonth());
|
||||||
|
return LocalDateTime.of(firstDay, LocalTime.MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期所在月的结束时间(最后一天 23:59:59)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getMonthEnd(LocalDateTime dateTime) {
|
||||||
|
LocalDate lastDay = dateTime.toLocalDate().with(TemporalAdjusters.lastDayOfMonth());
|
||||||
|
return LocalDateTime.of(lastDay, LocalTime.MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期所在年的开始时间(1月1日 00:00:00)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getYearStart(LocalDateTime dateTime) {
|
||||||
|
LocalDate firstDay = dateTime.toLocalDate().with(TemporalAdjusters.firstDayOfYear());
|
||||||
|
return LocalDateTime.of(firstDay, LocalTime.MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期所在年的结束时间(12月31日 23:59:59)
|
||||||
|
*/
|
||||||
|
public static LocalDateTime getYearEnd(LocalDateTime dateTime) {
|
||||||
|
LocalDate lastDay = dateTime.toLocalDate().with(TemporalAdjusters.lastDayOfYear());
|
||||||
|
return LocalDateTime.of(lastDay, LocalTime.MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 使用示例 ====================
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println("========== 当前时间范围 ==========");
|
||||||
|
System.out.println("本周开始: " + getWeekStart());
|
||||||
|
System.out.println("本周结束: " + getWeekEnd());
|
||||||
|
System.out.println("本月开始: " + getMonthStart());
|
||||||
|
System.out.println("本月结束: " + getMonthEnd());
|
||||||
|
System.out.println("本年开始: " + getYearStart());
|
||||||
|
System.out.println("本年结束: " + getYearEnd());
|
||||||
|
|
||||||
|
System.out.println("\n========== 指定时间范围 ==========");
|
||||||
|
LocalDateTime customTime = LocalDateTime.of(2026, 7, 15, 14, 30, 0);
|
||||||
|
System.out.println("指定时间: " + customTime);
|
||||||
|
System.out.println("所在周开始: " + getWeekStart(customTime));
|
||||||
|
System.out.println("所在周结束: " + getWeekEnd(customTime));
|
||||||
|
System.out.println("所在月开始: " + getMonthStart(customTime));
|
||||||
|
System.out.println("所在月结束: " + getMonthEnd(customTime));
|
||||||
|
System.out.println("所在年开始: " + getYearStart(customTime));
|
||||||
|
System.out.println("所在年结束: " + getYearEnd(customTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package org.jeecg.common.vo.result;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DataCenterDataSummary {
|
||||||
|
|
||||||
|
private String weekHtml;
|
||||||
|
private String monthHtml;
|
||||||
|
private String yearHtml;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.jeecg.common.vo.statistic;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AlertReport {
|
||||||
|
/**
|
||||||
|
* 异常项名称
|
||||||
|
*/
|
||||||
|
private String itemName;
|
||||||
|
/**
|
||||||
|
* 异常项单位
|
||||||
|
*/
|
||||||
|
private String itemUnit;
|
||||||
|
/**
|
||||||
|
* 极限值
|
||||||
|
*/
|
||||||
|
private String extremeValue;
|
||||||
|
/**
|
||||||
|
* 异常次数
|
||||||
|
*/
|
||||||
|
private Integer alertCount;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue