package com.ruoyi.biz.service.impl; import com.ruoyi.biz.domain.TwinCalc2hr; import com.ruoyi.biz.domain.TwinDevice; import com.ruoyi.biz.mapper.TwinCalc2hrMapper; import com.ruoyi.biz.service.IIotService; import com.ruoyi.biz.service.ITwinCalc2hrService; import com.ruoyi.biz.service.ITwinDeviceService; import com.ruoyi.common.core.text.Convert; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; /** * 2小时统计数据Service业务层处理 * * @author ruoyi * @date 2024-05-12 */ @Service public class TwinCalc2hrServiceImpl implements ITwinCalc2hrService { @Resource private TwinCalc2hrMapper twinCalc2hrMapper; @Resource private ITwinDeviceService deviceService; @Resource private IIotService iotService; @Resource private AsyncServiceImpl asyncService; /** * 查询2小时统计数据 * * @param id 2小时统计数据主键 * @return 2小时统计数据 */ @Override public TwinCalc2hr selectTwinCalc2hrById(Long id) { return twinCalc2hrMapper.selectTwinCalc2hrById(id); } /** * 查询2小时统计数据列表 * * @param twinCalc2hr 2小时统计数据 * @return 2小时统计数据 */ @Override public List selectTwinCalc2hrList(TwinCalc2hr twinCalc2hr) { return twinCalc2hrMapper.selectTwinCalc2hrList(twinCalc2hr); } /** * 新增2小时统计数据 * * @param twinCalc2hr 2小时统计数据 * @return 结果 */ @Override public int insertTwinCalc2hr(TwinCalc2hr twinCalc2hr) { return twinCalc2hrMapper.insertTwinCalc2hr(twinCalc2hr); } /** * 修改2小时统计数据 * * @param twinCalc2hr 2小时统计数据 * @return 结果 */ @Override public int updateTwinCalc2hr(TwinCalc2hr twinCalc2hr) { return twinCalc2hrMapper.updateTwinCalc2hr(twinCalc2hr); } /** * 批量删除2小时统计数据 * * @param ids 需要删除的2小时统计数据主键 * @return 结果 */ @Override public int deleteTwinCalc2hrByIds(String ids) { return twinCalc2hrMapper.deleteTwinCalc2hrByIds(Convert.toStrArray(ids)); } /** * 删除2小时统计数据信息 * * @param id 2小时统计数据主键 * @return 结果 */ @Override public int deleteTwinCalc2hrById(Long id) { return twinCalc2hrMapper.deleteTwinCalc2hrById(id); } /** * 获取上一个时段 * * @return 时段 1-12 */ @Override public TwinCalc2hr lastPeriod() { return twinCalc2hrMapper.lastPeriod(); } /** * 计算当天的统计数据 * * @return 统计数据 */ @Override public TwinCalc2hr calcToday() { TwinCalc2hr calc2hr = twinCalc2hrMapper.calcToday(); TwinCalc2hr curr2hr = calcCurr(); if (calc2hr != null) { //解决当天 0-2点这个时间段的尴尬 calc2hr.calc(curr2hr); return calc2hr; } else { return curr2hr; } } /** * 计算指定日期的统计数据 * * @param date 指定日期 * @return 统计数据 */ @Override public TwinCalc2hr calc4date(Date date) { return twinCalc2hrMapper.calc4date(date); } /** * 根据设备ID查询指定时间之后的日统计数据 * * @param date 指定时间 * @param id 设备ID * @return 列表 */ @Override public List selectTwinCalc2hrListByTime(Date date, Long id) { return twinCalc2hrMapper.selectTwinCalc2hrListByTime(date, id); } /** * 按设备分类统计日数据 * * @param start 开始时间 * @param end 结束时间 * @return 列表 */ @Override public List calc2hrList(Date start, Date end) { return twinCalc2hrMapper.calc2hrList(start, end); } /** * 查询指定设备的周统计数据 * * @param twinDevice 设备对象 * @return 列表 */ @Override public List selectWeekData(TwinDevice twinDevice) { /* *获取最近7天的数据,当天的数据需要单独处理一下 */ LocalDate localDate = LocalDate.now().minusDays(7); Date date = Date.from(localDate.atStartOfDay(ZoneOffset.of("+8")).toInstant()); List list = twinCalc2hrMapper.selectTwinCalc2hrListByTime(date, twinDevice.getId()); TwinCalc2hr today = list.get(list.size() - 1); //获取上一个时段 Long lastPeriod = today.getTimePeriod(); LocalDateTime start = LocalDateTime.of(LocalDate.now(), LocalTime.MIN); if (lastPeriod != 12L) { //如果为12,则代表是前一天的,那就从今天0点开始 start = start.plusHours(2 * lastPeriod); start = start.minusSeconds(1); //获取时段范围 时间 1=0-2点 2=2-4 LocalDateTime end = LocalDateTime.now(); Long startTime = start.toInstant(ZoneOffset.of("+8")).toEpochMilli(); Long endTime = end.toInstant(ZoneOffset.of("+8")).toEpochMilli(); Future>> future = asyncService.process(twinDevice, new Date(), startTime, endTime, 0); try { Map> map = future.get(); List calc2hrs = (List) map.get("calc"); for (TwinCalc2hr calc2hr : calc2hrs) { today.calc(calc2hr); } } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); } } return list; } /** * 统计上一个偶数时间至当前的数据 */ private TwinCalc2hr calcCurr() { TwinCalc2hr result = new TwinCalc2hr(true); result.setDataDate(new Date()); //获取上一个时段 TwinCalc2hr last = lastPeriod(); Long lastPeriod = last.getTimePeriod(); LocalDateTime start = LocalDateTime.of(LocalDate.now(), LocalTime.MIN); if (lastPeriod != 12L) { //如果为12,则代表是前一天的,那就从今天0点开始 start = start.plusHours(2 * lastPeriod); } start = start.minusSeconds(1); //获取时段范围 时间 1=0-2点 2=2-4 LocalDateTime end = LocalDateTime.now(); Long startTime = start.toInstant(ZoneOffset.of("+8")).toEpochMilli(); Long endTime = end.toInstant(ZoneOffset.of("+8")).toEpochMilli(); //为了避免多线程同时获取token导致重复执行,先执行一次获取token iotService.getToken(); List list = deviceService.selectTwinDeviceList(new TwinDevice()); List>>> futureList = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { TwinDevice twinDevice = list.get(i); futureList.add(asyncService.process(twinDevice, new Date(), startTime, endTime, 0)); } try { for (Future>> future : futureList) { Map> map = future.get(); List calc2hrs = (List) map.get("calc"); for (TwinCalc2hr calc2hr : calc2hrs) { result.calc(calc2hr); } } } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); } return result; } }