|
@ -11,6 +11,8 @@ import com.example.demo.service.GeneralService; |
|
|
import com.example.demo.service.StatisticsService; |
|
|
import com.example.demo.service.StatisticsService; |
|
|
import com.example.demo.service.WorkbenchService; |
|
|
import com.example.demo.service.WorkbenchService; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
|
|
import org.springframework.cache.annotation.Cacheable; |
|
|
|
|
|
import org.springframework.data.redis.core.RedisTemplate; |
|
|
import org.springframework.stereotype.Service; |
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
|
import java.time.LocalDate; |
|
|
import java.time.LocalDate; |
|
@ -19,6 +21,7 @@ import java.time.LocalDateTime; |
|
|
import java.time.LocalTime; |
|
|
import java.time.LocalTime; |
|
|
import java.time.ZoneId; |
|
|
import java.time.ZoneId; |
|
|
import java.util.*; |
|
|
import java.util.*; |
|
|
|
|
|
import java.util.function.Function; |
|
|
import java.util.stream.Collectors; |
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
@ -32,71 +35,94 @@ import java.util.stream.Collectors; |
|
|
|
|
|
|
|
|
@Service |
|
|
@Service |
|
|
public class WorkbenchServiceImpl implements WorkbenchService { |
|
|
public class WorkbenchServiceImpl implements WorkbenchService { |
|
|
|
|
|
|
|
|
|
|
|
private final RedisTemplate<String, WorkbenchCard> redisTemplate; |
|
|
|
|
|
// private final StatisticsMapper statisticsMapper; |
|
|
@Autowired |
|
|
@Autowired |
|
|
private WorkBenchMapper workBenchMapper; |
|
|
private WorkBenchMapper workBenchMapper; |
|
|
@Autowired |
|
|
@Autowired |
|
|
private GeneralService generalService; |
|
|
private GeneralService generalService; |
|
|
@Autowired |
|
|
@Autowired |
|
|
private StatisticsMapper statisticsMapper; |
|
|
private StatisticsMapper statisticsMapper; |
|
|
|
|
|
@Autowired |
|
|
|
|
|
public WorkbenchServiceImpl(RedisTemplate<String, WorkbenchCard> redisTemplate, StatisticsMapper statisticsMapper) { |
|
|
|
|
|
this.redisTemplate = redisTemplate; |
|
|
|
|
|
this.statisticsMapper = statisticsMapper; |
|
|
|
|
|
} |
|
|
|
|
|
private static final String CACHE_KEY = "workbench_card_cache"; |
|
|
@Override |
|
|
@Override |
|
|
public WorkbenchCard getCard( ) { |
|
|
public WorkbenchCard getCard( ) { |
|
|
Date date=new Date();//当天 |
|
|
|
|
|
Date yday=generalService.getYesterday(); |
|
|
|
|
|
// 获取开始时间和结束时间(当天) |
|
|
// 获取开始时间和结束时间(当天) |
|
|
LocalDateTime startOfDay = date.toInstant() |
|
|
|
|
|
.atZone(ZoneId.systemDefault()) |
|
|
|
|
|
.toLocalDateTime() |
|
|
|
|
|
.with(LocalTime.MIN); |
|
|
|
|
|
|
|
|
LocalDateTime startOfDay = LocalDateTime.now().with(LocalTime.MIN); |
|
|
LocalDateTime endOfDay = startOfDay.plusDays(1).minusSeconds(1); |
|
|
LocalDateTime endOfDay = startOfDay.plusDays(1).minusSeconds(1); |
|
|
// 获取开始时间和结束时间(当天) |
|
|
|
|
|
LocalDateTime startOfYday = yday.toInstant() |
|
|
|
|
|
.atZone(ZoneId.systemDefault()) |
|
|
|
|
|
.toLocalDateTime() |
|
|
|
|
|
.with(LocalTime.MIN); |
|
|
|
|
|
LocalDateTime endOfYday = startOfYday.plusDays(1).minusSeconds(1); |
|
|
|
|
|
// 获取当前日期 |
|
|
|
|
|
LocalDate today = LocalDate.now(); |
|
|
|
|
|
|
|
|
// 获取开始时间和结束时间(昨天) |
|
|
|
|
|
LocalDateTime startOfYday = startOfDay.minusDays(1); |
|
|
|
|
|
LocalDateTime endOfYday = endOfDay.minusDays(1); |
|
|
|
|
|
|
|
|
// 获取当前年份的第一天 |
|
|
// 获取当前年份的第一天 |
|
|
LocalDate firstDayOfYear = today.withDayOfYear(1); |
|
|
|
|
|
// 将年份的第一天日期转换为Date类型 |
|
|
|
|
|
Date yearlyStartDate=Date.from(firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant()); |
|
|
|
|
|
|
|
|
LocalDate firstDayOfYear = LocalDate.now().withDayOfYear(1); |
|
|
|
|
|
Date yearlyStartDate = Date.from(firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant()); |
|
|
List<String> markets = generalService.getMarket(); |
|
|
List<String> markets = generalService.getMarket(); |
|
|
|
|
|
|
|
|
|
|
|
// 批量获取统计数据 |
|
|
|
|
|
List<Statistics> currentStatsList = statisticsMapper.selectByMarketsAndDate(markets, |
|
|
|
|
|
Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()), |
|
|
|
|
|
Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant())); |
|
|
|
|
|
|
|
|
|
|
|
List<Statistics> ydayStatsList = statisticsMapper.selectByMarketsAndDate(markets, |
|
|
|
|
|
Date.from(startOfYday.atZone(ZoneId.systemDefault()).toInstant()), |
|
|
|
|
|
Date.from(endOfYday.atZone(ZoneId.systemDefault()).toInstant())); |
|
|
|
|
|
// 将 List<Statistics> 转换为 Map<String, Statistics> |
|
|
|
|
|
Map<String, Statistics> currentStatsMap = currentStatsList.stream() |
|
|
|
|
|
.collect(Collectors.toMap(Statistics::getMarket, Function.identity(), (existing, replacement) -> existing)); |
|
|
|
|
|
|
|
|
|
|
|
Map<String, Statistics> ydayStatsMap = ydayStatsList.stream() |
|
|
|
|
|
.collect(Collectors.toMap(Statistics::getMarket, Function.identity(), (existing, replacement) -> existing)); |
|
|
|
|
|
|
|
|
// 并行处理市场列表,创建市场卡片列表 |
|
|
// 并行处理市场列表,创建市场卡片列表 |
|
|
List<WorkbenchMarketCard> marketCards = markets.parallelStream() |
|
|
List<WorkbenchMarketCard> marketCards = markets.parallelStream() |
|
|
// 过滤掉空或全空格的市场名称 |
|
|
|
|
|
.filter(market -> market != null && !market.trim().isEmpty()) |
|
|
.filter(market -> market != null && !market.trim().isEmpty()) |
|
|
.map(market -> { |
|
|
|
|
|
// 根据市场名称和日期范围查询统计信息 |
|
|
|
|
|
Statistics currentStatistics = statisticsMapper.selectByMarketAndDate( |
|
|
|
|
|
market, |
|
|
|
|
|
Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()), |
|
|
|
|
|
Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant()) |
|
|
|
|
|
); |
|
|
|
|
|
Statistics ydayStatistics = statisticsMapper.selectByMarketAndDate( |
|
|
|
|
|
market, |
|
|
|
|
|
Date.from(startOfYday.atZone(ZoneId.systemDefault()).toInstant()), |
|
|
|
|
|
Date.from(endOfYday.atZone(ZoneId.systemDefault()).toInstant()) |
|
|
|
|
|
); |
|
|
|
|
|
// 创建并返回市场卡片对象 |
|
|
|
|
|
return createWorkbenchMarketCard(market, currentStatistics,ydayStatistics, yearlyStartDate, date); |
|
|
|
|
|
}) |
|
|
|
|
|
// 收集并行流结果为列表 |
|
|
|
|
|
|
|
|
.map(market -> createWorkbenchMarketCard( |
|
|
|
|
|
market, |
|
|
|
|
|
currentStatsMap.getOrDefault(market, null), |
|
|
|
|
|
ydayStatsMap.getOrDefault(market, null), |
|
|
|
|
|
|
|
|
|
|
|
new Date())) |
|
|
.collect(Collectors.toList()); |
|
|
.collect(Collectors.toList()); |
|
|
|
|
|
|
|
|
return new WorkbenchCard( marketCards,new ArrayList<>(), markets, date, date); |
|
|
|
|
|
|
|
|
return new WorkbenchCard(marketCards, new ArrayList<>(), markets, new Date(), new Date()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
public WorkbenchCard getCardCache() { |
|
|
|
|
|
WorkbenchCard cached = redisTemplate.opsForValue().get(CACHE_KEY); |
|
|
|
|
|
if (cached != null) { |
|
|
|
|
|
System.out.println("读取缓存数据: " + new Date()); |
|
|
|
|
|
return cached; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
WorkbenchCard freshData = getCard(); |
|
|
|
|
|
redisTemplate.opsForValue().set(CACHE_KEY, freshData, 1, java.util.concurrent.TimeUnit.HOURS); |
|
|
|
|
|
System.out.println("刷新缓存并存储新数据: " + new Date()); |
|
|
|
|
|
return freshData; |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
System.err.println("查询数据库失败,尝试使用旧缓存数据或抛出异常:" + e.getMessage()); |
|
|
|
|
|
throw e; // 或者你可以选择返回上次的缓存数据(如果有) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
获取卡片数据 |
|
|
获取卡片数据 |
|
|
*/ |
|
|
*/ |
|
|
@Override |
|
|
@Override |
|
|
public WorkbenchMarketCard createWorkbenchMarketCard(String market,Statistics currentStatistics, Statistics ydayStatistics, Date yearlyStartDate, Date currentDate) { |
|
|
|
|
|
|
|
|
public WorkbenchMarketCard createWorkbenchMarketCard(String market,Statistics currentStatistics, Statistics ydayStatistics, Date currentDate) { |
|
|
Date date=new Date(); |
|
|
Date date=new Date(); |
|
|
WorkbenchMarketCard card = new WorkbenchMarketCard(); |
|
|
WorkbenchMarketCard card = new WorkbenchMarketCard(); |
|
|
card.setMarket(market); |
|
|
card.setMarket(market); |
|
|
if (currentStatistics != null&& ydayStatistics != null) { |
|
|
if (currentStatistics != null&& ydayStatistics != null) { |
|
|
// 一次性获取全年统计数据(从年初到今天) |
|
|
// 一次性获取全年统计数据(从年初到今天) |
|
|
Map<String, Integer> yearlyStats = calculateAllSum(market, yearlyStartDate, date); |
|
|
|
|
|
|
|
|
// Map<String, Integer> yearlyStats = calculateAllSum(market, yearlyStartDate, date); |
|
|
// 卡片一:当前金币相关 |
|
|
// 卡片一:当前金币相关 |
|
|
card.setCurrentPermanent(currentStatistics.getCurrentPermanent());//余量-永久金币 |
|
|
card.setCurrentPermanent(currentStatistics.getCurrentPermanent());//余量-永久金币 |
|
|
card.setCurrentFreeJune(currentStatistics.getCurrentFreeJune()); //余量-免费六月金币 |
|
|
card.setCurrentFreeJune(currentStatistics.getCurrentFreeJune()); //余量-免费六月金币 |
|
@ -108,8 +134,8 @@ public class WorkbenchServiceImpl implements WorkbenchService { |
|
|
// 卡片二:充值相关 |
|
|
// 卡片二:充值相关 |
|
|
card.setRecharge(ydayStatistics.getRecharge()); //充值-昨日充值 |
|
|
card.setRecharge(ydayStatistics.getRecharge()); //充值-昨日充值 |
|
|
card.setMoney(ydayStatistics.getMoney()); //充值-昨日金额(永久) |
|
|
card.setMoney(ydayStatistics.getMoney()); //充值-昨日金额(永久) |
|
|
card.setYearlyRecharge(yearlyStats.getOrDefault("recharge", 0)); // 充值-全年累计充值 |
|
|
|
|
|
card.setYearlyMoney(yearlyStats.getOrDefault("money", 0)); // 充值-全年累计金额(永久)//充值-全年累计金额(永久) |
|
|
|
|
|
|
|
|
card.setYearlyRecharge(currentStatistics.getYearlyRecharge()); // 充值-全年累计充值 |
|
|
|
|
|
card.setYearlyMoney(currentStatistics.getYearlyMoney()); // 充值-全年累计金额(永久)//充值-全年累计金额(永久) |
|
|
// 卡片三:消费与退款 |
|
|
// 卡片三:消费与退款 |
|
|
card.setConsumePermanent(ydayStatistics.getConsumePermanent());//昨日消费-永久金币 |
|
|
card.setConsumePermanent(ydayStatistics.getConsumePermanent());//昨日消费-永久金币 |
|
|
card.setConsumeFreeJune(ydayStatistics.getConsumeFreeJune());//昨日消费-免费六月金币 |
|
|
card.setConsumeFreeJune(ydayStatistics.getConsumeFreeJune());//昨日消费-免费六月金币 |
|
@ -124,20 +150,20 @@ public class WorkbenchServiceImpl implements WorkbenchService { |
|
|
//昨日总退款 |
|
|
//昨日总退款 |
|
|
int totalRefund = card.getRefundPermanent() + card.getRefundFreeJune() + card.getRefundFreeDecember() + card.getRefundTask(); |
|
|
int totalRefund = card.getRefundPermanent() + card.getRefundFreeJune() + card.getRefundFreeDecember() + card.getRefundTask(); |
|
|
card.setDailyReduce(totalConsume - totalRefund);//昨日总消耗 |
|
|
card.setDailyReduce(totalConsume - totalRefund);//昨日总消耗 |
|
|
card.setYearlyConsume(yearlyStats.getOrDefault("consume", 0)); // 年累计消费 |
|
|
|
|
|
card.setYearlyRefund(yearlyStats.getOrDefault("refund", 0)); // 年累计退款 |
|
|
|
|
|
|
|
|
card.setYearlyConsume(currentStatistics.getYearlyConsume()); // 年累计消费 |
|
|
|
|
|
card.setYearlyRefund(currentStatistics.getYearlyRefund()); // 年累计退款 |
|
|
card.setYearlyReduce(card.getYearlyConsume() - card.getYearlyRefund());//年累计消耗 |
|
|
card.setYearlyReduce(card.getYearlyConsume() - card.getYearlyRefund());//年累计消耗 |
|
|
// 卡片四:人头数相关 |
|
|
// 卡片四:人头数相关 |
|
|
card.setRechargeNum(currentStatistics.getRechargeNum()); |
|
|
card.setRechargeNum(currentStatistics.getRechargeNum()); |
|
|
card.setFirstRecharge(currentStatistics.getFirstRecharge()); |
|
|
card.setFirstRecharge(currentStatistics.getFirstRecharge()); |
|
|
card.setYearlyRechargeNum(yearlyStats.getOrDefault("rechargeNum", 0)); |
|
|
|
|
|
|
|
|
card.setYearlyRechargeNum(currentStatistics.getYearlyRechargeNum()); |
|
|
// 周环比、日同比 |
|
|
// 周环比、日同比 |
|
|
card.setWow(calculateWeekOverWeek(market, currentDate)); |
|
|
card.setWow(calculateWeekOverWeek(market, currentDate)); |
|
|
card.setSumWow(calculateAllWeekOverWeek(date)); |
|
|
card.setSumWow(calculateAllWeekOverWeek(date)); |
|
|
card.setDaily(calculateDayOverDay(market, currentDate)); |
|
|
card.setDaily(calculateDayOverDay(market, currentDate)); |
|
|
card.setSumDaily(calculateAllDayOverDay(date)); |
|
|
card.setSumDaily(calculateAllDayOverDay(date)); |
|
|
//更新时间 |
|
|
|
|
|
card.setUpdateTime(currentStatistics.getUpdateTime()); |
|
|
|
|
|
|
|
|
/* //更新时间 |
|
|
|
|
|
card.setUpdateTime(currentStatistics.getUpdateTime());*/ |
|
|
} |
|
|
} |
|
|
return card; |
|
|
return card; |
|
|
} |
|
|
} |
|
@ -166,6 +192,7 @@ public class WorkbenchServiceImpl implements WorkbenchService { |
|
|
根据类型获取统计数据 |
|
|
根据类型获取统计数据 |
|
|
*/ |
|
|
*/ |
|
|
@Override |
|
|
@Override |
|
|
|
|
|
|
|
|
public Map<String, Integer> calculateAllSum(String market, Date startDate, Date endDate) { |
|
|
public Map<String, Integer> calculateAllSum(String market, Date startDate, Date endDate) { |
|
|
WorkbenchFullStatistics stats = workBenchMapper.getFullStatisticsByMarketAndDate(market, startDate, endDate); |
|
|
WorkbenchFullStatistics stats = workBenchMapper.getFullStatisticsByMarketAndDate(market, startDate, endDate); |
|
|
Map<String, Integer> result = new HashMap<>(); |
|
|
Map<String, Integer> result = new HashMap<>(); |
|
|