package com.xy.xyaicpzs.service; import lombok.RequiredArgsConstructor; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.TimeUnit; /** * 页面访问量统计服务 * 使用Redis实现PV统计 */ @Service @RequiredArgsConstructor public class PageViewService { private final RedisTemplate redisTemplate; // Redis Key前缀 private static final String PV_TOTAL_KEY = "pv:total"; // 总PV private static final String PV_DAILY_KEY = "pv:daily:"; // 每日PV前缀 private static final int MAX_DAYS = 90; // 最大保存天数 /** * 增加页面访问量 */ public void incrementPageView() { String today = LocalDate.now().format(DateTimeFormatter.ISO_DATE); // 增加总PV redisTemplate.opsForValue().increment(PV_TOTAL_KEY); // 增加今日总PV String dailyKey = PV_DAILY_KEY + today; redisTemplate.opsForValue().increment(dailyKey); // 设置过期时间为90天 redisTemplate.expire(dailyKey, MAX_DAYS, TimeUnit.DAYS); } /** * 获取总PV */ public Long getTotalPageViews() { Object value = redisTemplate.opsForValue().get(PV_TOTAL_KEY); return value != null ? Long.parseLong(value.toString()) : 0L; } /** * 获取今日总PV */ public Long getTodayPageViews() { String today = LocalDate.now().format(DateTimeFormatter.ISO_DATE); Object value = redisTemplate.opsForValue().get(PV_DAILY_KEY + today); return value != null ? Long.parseLong(value.toString()) : 0L; } /** * 获取指定日期的PV * @param date 日期,格式:yyyy-MM-dd */ public Long getDailyPageViews(String date) { Object value = redisTemplate.opsForValue().get(PV_DAILY_KEY + date); return value != null ? Long.parseLong(value.toString()) : 0L; } /** * 根据日期范围获取PV统计(近7天/30天/90天) * @param days 天数,最大90天 * @return 日期和对应PV的Map,按日期倒序排列 */ public Map getPageViewsByDays(int days) { // 限制最大天数为90天 if (days > MAX_DAYS) { days = MAX_DAYS; } Map result = new LinkedHashMap<>(); LocalDate today = LocalDate.now(); DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE; for (int i = 0; i < days; i++) { String date = today.minusDays(i).format(formatter); Long pv = getDailyPageViews(date); result.put(date, pv); } return result; } }