package com.ruoyi.system.service.impl; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.dto.SysDashboardOverviewRequest; import com.ruoyi.system.mapper.SysDashboardMapper; import com.ruoyi.system.service.ISysDashboardService; import com.ruoyi.system.service.ISysVisitorRecordService; import com.ruoyi.system.vo.SysDashboardOverviewVO; import com.ruoyi.system.vo.SysDashboardRegisterSummaryVO; import com.ruoyi.system.vo.SysDashboardStatusSummaryVO; import com.ruoyi.system.vo.SysDashboardTrendDailyVO; import com.ruoyi.system.vo.SysDashboardTrendVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 首页数据总览服务实现 * * @author ruoyi */ @Service public class SysDashboardServiceImpl implements ISysDashboardService { private static final String PERIOD_TODAY = "TODAY"; private static final String PERIOD_RECENT_7_DAYS = "RECENT_7_DAYS"; private static final String PERIOD_RECENT_30_DAYS = "RECENT_30_DAYS"; private static final DateTimeFormatter DAY_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); private static final DateTimeFormatter LABEL_FORMATTER = DateTimeFormatter.ofPattern("MM-dd"); @Autowired private SysDashboardMapper dashboardMapper; @Autowired private ISysVisitorRecordService visitorRecordService; @Override public SysDashboardOverviewVO overview(SysDashboardOverviewRequest request) { visitorRecordService.refreshVisitorStatus(); DateRange range = resolveDateRange(request); SysDashboardOverviewVO overview = new SysDashboardOverviewVO(); overview.setPeriodType(range.getPeriodType()); overview.setBeginTime(range.getBeginTime()); overview.setEndTime(range.getEndTime()); overview.setOnlineAppointment(defaultRegisterSummary( dashboardMapper.selectRegisterSummary("APPOINTMENT", range.getBeginTime(), range.getEndTime()))); overview.setOnsiteAppointment(defaultRegisterSummary( dashboardMapper.selectRegisterSummary("ONSITE", range.getBeginTime(), range.getEndTime()))); overview.setStatusSummary(defaultStatusSummary(dashboardMapper.selectStatusSummary())); overview.setTrend(buildTrend(range, dashboardMapper.selectTrendDaily(range.getBeginTime(), range.getEndTime()))); return overview; } private DateRange resolveDateRange(SysDashboardOverviewRequest request) { if (request != null && request.getBeginTime() != null && request.getEndTime() != null && request.getEndTime().after(request.getBeginTime())) { return new DateRange("CUSTOM", request.getBeginTime(), request.getEndTime()); } String periodType = request == null ? null : StringUtils.trim(request.getPeriodType()); if (!PERIOD_TODAY.equals(periodType) && !PERIOD_RECENT_30_DAYS.equals(periodType)) { periodType = PERIOD_RECENT_7_DAYS; } LocalDate today = LocalDate.now(); int days = PERIOD_TODAY.equals(periodType) ? 1 : (PERIOD_RECENT_30_DAYS.equals(periodType) ? 30 : 7); LocalDate beginDate = today.minusDays(days - 1L); LocalDate endDate = today.plusDays(1L); return new DateRange(periodType, DateUtils.toDate(beginDate), DateUtils.toDate(endDate)); } private SysDashboardRegisterSummaryVO defaultRegisterSummary(SysDashboardRegisterSummaryVO summary) { SysDashboardRegisterSummaryVO result = summary == null ? new SysDashboardRegisterSummaryVO() : summary; result.setRegisterCount(defaultLong(result.getRegisterCount())); result.setVehicleCount(defaultLong(result.getVehicleCount())); return result; } private SysDashboardStatusSummaryVO defaultStatusSummary(SysDashboardStatusSummaryVO summary) { SysDashboardStatusSummaryVO result = summary == null ? new SysDashboardStatusSummaryVO() : summary; result.setVisitingCount(defaultLong(result.getVisitingCount())); result.setSignedOutCount(defaultLong(result.getSignedOutCount())); result.setOverdueCount(defaultLong(result.getOverdueCount())); return result; } private SysDashboardTrendVO buildTrend(DateRange range, List dailyList) { Map dailyMap = new HashMap<>(); if (dailyList != null) { for (SysDashboardTrendDailyVO daily : dailyList) { dailyMap.put(daily.getTrendDate(), daily); } } LocalDate beginDate = toLocalDate(range.getBeginTime()); LocalDate endDate = toLocalDate(range.getEndTime()); long days = Math.max(1L, ChronoUnit.DAYS.between(beginDate, endDate)); List labels = new ArrayList<>(); List onsite = new ArrayList<>(); List appointment = new ArrayList<>(); List vehicle = new ArrayList<>(); for (int i = 0; i < days; i++) { LocalDate current = beginDate.plusDays(i); String trendDate = DAY_FORMATTER.format(current); SysDashboardTrendDailyVO daily = dailyMap.get(trendDate); labels.add(LABEL_FORMATTER.format(current)); onsite.add(defaultLong(daily == null ? null : daily.getOnsiteCount())); appointment.add(defaultLong(daily == null ? null : daily.getAppointmentCount())); vehicle.add(defaultLong(daily == null ? null : daily.getVehicleCount())); } SysDashboardTrendVO trend = new SysDashboardTrendVO(); trend.setLabels(labels); trend.setOnsite(onsite); trend.setAppointment(appointment); trend.setVehicle(vehicle); return trend; } private LocalDate toLocalDate(Date date) { return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); } private Long defaultLong(Long value) { return value == null ? 0L : value; } private static class DateRange { private final String periodType; private final Date beginTime; private final Date endTime; private DateRange(String periodType, Date beginTime, Date endTime) { this.periodType = periodType; this.beginTime = beginTime; this.endTime = endTime; } public String getPeriodType() { return periodType; } public Date getBeginTime() { return beginTime; } public Date getEndTime() { return endTime; } } }