You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
308 lines
16 KiB
308 lines
16 KiB
package com.example.demo.serviceImpl;
|
|
|
|
import com.example.demo.domain.entity.Statistics;
|
|
import com.example.demo.domain.vo.WorkbenchCard;
|
|
import com.example.demo.domain.vo.WorkbenchMarketCard;
|
|
import com.example.demo.mapper.StatisticsMapper;
|
|
import com.example.demo.mapper.WorkBenchMapper;
|
|
import com.example.demo.service.GeneralService;
|
|
import com.example.demo.service.StatisticsService;
|
|
import com.example.demo.service.WorkbenchService;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.time.LocalDate;
|
|
import java.time.DayOfWeek;
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalTime;
|
|
import java.time.ZoneId;
|
|
import java.util.ArrayList;
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* @program: gold-java
|
|
* @ClassName WorkbenchServiceImpl
|
|
* @description:
|
|
* @author: Ethan
|
|
* @create: 2025−06-18 10:47
|
|
* @Version 1.0
|
|
**/
|
|
|
|
@Service
|
|
public class WorkbenchServiceImpl implements WorkbenchService {
|
|
@Autowired
|
|
private WorkBenchMapper workBenchMapper;
|
|
@Autowired
|
|
private GeneralService generalService;
|
|
@Autowired
|
|
private StatisticsMapper statisticsMapper;
|
|
@Override
|
|
public WorkbenchCard getCard(String token) {
|
|
Date date=new Date();
|
|
// 获取开始时间和结束时间(当天)
|
|
LocalDateTime startOfDay = date.toInstant()
|
|
.atZone(ZoneId.systemDefault())
|
|
.toLocalDateTime()
|
|
.with(LocalTime.MIN);
|
|
|
|
LocalDateTime endOfDay = startOfDay.plusDays(1).minusSeconds(1);
|
|
// 获取当前日期
|
|
LocalDate today = LocalDate.now();
|
|
// 获取当前年份的第一天
|
|
LocalDate firstDayOfYear = today.withDayOfYear(1);
|
|
// 将年份的第一天日期转换为Date类型
|
|
Date yearlyStartDate=Date.from(firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
|
List<String> markets = generalService.getMarket();
|
|
// 并行处理市场列表,创建市场卡片列表
|
|
List<WorkbenchMarketCard> marketCards = markets.parallelStream()
|
|
// 过滤掉空或全空格的市场名称
|
|
.filter(market -> market != null && !market.trim().isEmpty())
|
|
.map(market -> {
|
|
// 根据市场名称和日期范围查询统计信息
|
|
Statistics statistics = statisticsMapper.selectByMarketAndDate(
|
|
market,
|
|
Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()),
|
|
Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant())
|
|
);
|
|
// 创建并返回市场卡片对象
|
|
return createWorkbenchMarketCard(market, statistics, yearlyStartDate, date);
|
|
})
|
|
// 收集并行流结果为列表
|
|
.collect(Collectors.toList());
|
|
|
|
return new WorkbenchCard(token, marketCards, markets, date, date);
|
|
/* List<WorkbenchMarketCard> marketCards = new ArrayList<>();
|
|
// 遍历每个 marketCard 并填充数据
|
|
for (String market : markets) {
|
|
if (market == null || market.trim().isEmpty()) continue;
|
|
|
|
// 查询该地区当天的数据
|
|
Statistics statistics = statisticsMapper.selectByMarketAndDate(
|
|
market,
|
|
Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()),
|
|
Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant())
|
|
);
|
|
WorkbenchMarketCard card = new WorkbenchMarketCard();
|
|
card.setMarket(market);
|
|
if (statistics != null){
|
|
|
|
// 卡片一:当前金币相关
|
|
card.setCurrentPermanent(statistics.getCurrentPermanent());//余量-永久金币
|
|
card.setCurrentFreeJune(statistics.getCurrentFreeJune()); //余量-免费六月金币
|
|
card.setCurrentFreeDecember(statistics.getCurrentFreeDecember()); //余量-免费十二月金币
|
|
card.setCurrentTask(statistics.getCurrentTask()); //余量-任务金币
|
|
card.setCurrentFree(card.getCurrentFreeJune() + card.getCurrentFreeDecember()); //余量-免费金币
|
|
card.setCurrentGold(card.getCurrentPermanent() + card.getCurrentFree() + card.getCurrentTask()); //余量-总金币
|
|
card.setDailyChange(statistics.getDailyChange()); //较前一日变化
|
|
// 卡片二:充值相关
|
|
card.setRecharge(statistics.getRecharge()); //充值-当日充值
|
|
card.setMoney(statistics.getMoney()); //充值-当日金额(永久)
|
|
card.setYearlyRecharge(calculateSum(market, "recharge",yearlyStartDate ,date));//充值-全年累计充值
|
|
card.setYearlyMoney(calculateSum(market, "money",yearlyStartDate ,date)); //充值-全年累计金额(永久)
|
|
// 卡片三:消费与退款
|
|
card.setConsumePermanent(statistics.getConsumePermanent());//消费-永久金币
|
|
card.setConsumeFreeJune(statistics.getConsumeFreeJune());//消费-免费六月金币
|
|
card.setConsumeFreeDecember(statistics.getConsumeFreeDecember());//消费-免费十二月金币
|
|
card.setConsumeTask(statistics.getConsumeTask());//消费-任务金币
|
|
card.setRefundPermanent(statistics.getRefundPermanent());//退款-永久金币
|
|
card.setRefundFreeJune(statistics.getRefundFreeJune());//退款-免费六月金币
|
|
card.setRefundFreeDecember(statistics.getRefundFreeDecember());//退款-免费十二月金币
|
|
card.setRefundTask(statistics.getRefundTask());//退款-任务金币
|
|
//当日总消费
|
|
int totalConsume = card.getConsumePermanent() + card.getConsumeFreeJune() + card.getConsumeFreeDecember() + card.getConsumeTask();
|
|
//当日总退款
|
|
int totalRefund = card.getRefundPermanent() + card.getRefundFreeJune() + card.getRefundFreeDecember() + card.getRefundTask();
|
|
card.setDailyReduce(totalConsume - totalRefund);//当日总消耗
|
|
card.setYearlyConsume(calculateSum(market, "consume", yearlyStartDate,date));//年累计消费
|
|
card.setYearlyRefund(calculateSum(market, "refund",yearlyStartDate ,date));//年累计退款
|
|
card.setYearlyReduce(card.getYearlyConsume() - card.getYearlyRefund());//年累计消耗
|
|
// 卡片四:人头数相关
|
|
card.setRechargeNum(statistics.getRechargeNum());
|
|
card.setFirstRecharge(statistics.getFirstRecharge());
|
|
card.setYearlyRechargeNum(calculateSum(market,"rechargeNum",yearlyStartDate,date));
|
|
|
|
// 周环比、日同比
|
|
card.setWow(calculateWeekOverWeek(market, date));
|
|
card.setDaily(calculateDayOverDay(market, date));
|
|
|
|
marketCards.add(card);
|
|
}
|
|
|
|
}
|
|
return new WorkbenchCard(token, marketCards,markets,date,date);*/
|
|
}
|
|
/*
|
|
获取卡片数据
|
|
*/
|
|
@Override
|
|
public WorkbenchMarketCard createWorkbenchMarketCard(String market, Statistics statistics, Date yearlyStartDate, Date currentDate) {
|
|
Date date=new Date();
|
|
WorkbenchMarketCard card = new WorkbenchMarketCard();
|
|
card.setMarket(market);
|
|
if (statistics != null) {
|
|
// 卡片一:当前金币相关
|
|
card.setCurrentPermanent(statistics.getCurrentPermanent());//余量-永久金币
|
|
card.setCurrentFreeJune(statistics.getCurrentFreeJune()); //余量-免费六月金币
|
|
card.setCurrentFreeDecember(statistics.getCurrentFreeDecember()); //余量-免费十二月金币
|
|
card.setCurrentTask(statistics.getCurrentTask()); //余量-任务金币
|
|
card.setCurrentFree(card.getCurrentFreeJune() + card.getCurrentFreeDecember()); //余量-免费金币
|
|
card.setCurrentGold(card.getCurrentPermanent() + card.getCurrentFree() + card.getCurrentTask()); //余量-总金币
|
|
card.setDailyChange(statistics.getDailyChange()); //较前一日变化
|
|
// 卡片二:充值相关
|
|
card.setRecharge(statistics.getRecharge()); //充值-当日充值
|
|
card.setMoney(statistics.getMoney()); //充值-当日金额(永久)
|
|
card.setYearlyRecharge(calculateSum(market, "recharge",yearlyStartDate ,date));//充值-全年累计充值
|
|
card.setYearlyMoney(calculateSum(market, "money",yearlyStartDate ,date)); //充值-全年累计金额(永久)
|
|
// 卡片三:消费与退款
|
|
card.setConsumePermanent(statistics.getConsumePermanent());//消费-永久金币
|
|
card.setConsumeFreeJune(statistics.getConsumeFreeJune());//消费-免费六月金币
|
|
card.setConsumeFreeDecember(statistics.getConsumeFreeDecember());//消费-免费十二月金币
|
|
card.setConsumeTask(statistics.getConsumeTask());//消费-任务金币
|
|
card.setRefundPermanent(statistics.getRefundPermanent());//退款-永久金币
|
|
card.setRefundFreeJune(statistics.getRefundFreeJune());//退款-免费六月金币
|
|
card.setRefundFreeDecember(statistics.getRefundFreeDecember());//退款-免费十二月金币
|
|
card.setRefundTask(statistics.getRefundTask());//退款-任务金币
|
|
//当日总消费
|
|
int totalConsume = card.getConsumePermanent() + card.getConsumeFreeJune() + card.getConsumeFreeDecember() + card.getConsumeTask();
|
|
//当日总退款
|
|
int totalRefund = card.getRefundPermanent() + card.getRefundFreeJune() + card.getRefundFreeDecember() + card.getRefundTask();
|
|
card.setDailyReduce(totalConsume - totalRefund);//当日总消耗
|
|
card.setYearlyConsume(calculateSum(market, "consume", yearlyStartDate,date));//年累计消费
|
|
card.setYearlyRefund(calculateSum(market, "refund",yearlyStartDate ,date));//年累计退款
|
|
card.setYearlyReduce(card.getYearlyConsume() - card.getYearlyRefund());//年累计消耗
|
|
// 卡片四:人头数相关
|
|
card.setRechargeNum(statistics.getRechargeNum());
|
|
card.setFirstRecharge(statistics.getFirstRecharge());
|
|
card.setYearlyRechargeNum(calculateSum(market,"rechargeNum",yearlyStartDate,date));
|
|
|
|
|
|
// 周环比、日同比
|
|
card.setWow(calculateWeekOverWeek(market, currentDate));
|
|
card.setDaily(calculateDayOverDay(market, currentDate));
|
|
}
|
|
return card;
|
|
}
|
|
|
|
@Override
|
|
public WorkbenchCard getGraph(String token, Date startDate, Date endDate, List<String> markets) {
|
|
List<WorkbenchMarketCard> marketCards = new ArrayList<>();
|
|
|
|
for (String market : markets) {
|
|
WorkbenchMarketCard cards = new WorkbenchMarketCard();
|
|
cards.setMarket(market);
|
|
cards.setSumRechargePermanent(calculateSum(market, "money",startDate,endDate));
|
|
cards.setSumRechargeFree(calculateSum(market, "rFree",startDate,endDate));
|
|
cards.setSumConsumePermanent(calculateSum(market, "cPermanent",startDate,endDate));
|
|
cards.setSumConsumeFree(calculateSum(market, "cFree",startDate,endDate));
|
|
cards.setSumConsumeTask(calculateSum(market, "cTask",startDate,endDate));
|
|
marketCards.add( cards);
|
|
}
|
|
return new WorkbenchCard(token, marketCards,markets,startDate,endDate);
|
|
}
|
|
|
|
/*
|
|
根据类型获取统计数据
|
|
*/
|
|
@Override
|
|
public Integer calculateSum(String market, String type, Date startDate,Date endDate) {
|
|
|
|
//判断类型
|
|
switch
|
|
(type) {
|
|
case "recharge": //获取累计充值
|
|
return workBenchMapper.sumRecharge(market, startDate,endDate);
|
|
case "money": //获取累计金额(永久)
|
|
return workBenchMapper.sumMoney(market,startDate,endDate);
|
|
case "rFree": //获取累计充值(免费)
|
|
return workBenchMapper.sumRecharge(market,startDate,endDate)-
|
|
workBenchMapper.sumMoney(market,startDate,endDate);
|
|
case "consume": //获取累计消费
|
|
return workBenchMapper.sumConsume(market,startDate,endDate);
|
|
case "cPermanent": //获取累计消费-永久
|
|
return workBenchMapper.sumCPermanent(market,startDate,endDate);
|
|
case "cFree": //获取累计消费- 免费
|
|
return workBenchMapper.sumCFree(market,startDate,endDate);
|
|
case "cTask": //获取累计消费- 任务
|
|
return workBenchMapper.sumCTask(market,startDate,endDate);
|
|
case "refund": //获取累计退款
|
|
return workBenchMapper.sumRefund(market,startDate,endDate);
|
|
case "rechargeNum": //获取累计充值人数
|
|
return workBenchMapper.countRechargeNum(market,startDate,endDate);
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
/*
|
|
获取该日期该市场的日同比
|
|
*/
|
|
@Override
|
|
public Integer calculateDayOverDay(String market, Date date) {
|
|
//传入日期的数据
|
|
LocalDateTime startTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN);
|
|
LocalDateTime endTime= startTime.plusDays(1).minusSeconds(1);
|
|
Statistics currentStatistics = statisticsMapper.selectByMarketAndDate(market,
|
|
Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
|
|
Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
|
|
//空数据或数量为零,为避免0除数错误,返回增长率为0
|
|
if (currentStatistics == null || currentStatistics.getRechargeNum() == null) {
|
|
return 0;
|
|
}
|
|
Date yesterday = addDays(date, -1); //传入日期减一,昨天
|
|
Statistics yesterdayStatistics = statisticsMapper.selectByMarketAndDate(market,
|
|
Date.from(yesterday.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant()),
|
|
Date.from(yesterday.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant()));
|
|
//空数据或数量为零,为避免0除数错误,返回增长率为0
|
|
if (yesterdayStatistics == null || yesterdayStatistics.getRechargeNum() == null || yesterdayStatistics.getRechargeNum() == 0) {
|
|
return 0;
|
|
}
|
|
//计算增长率
|
|
double rate = ((double) (currentStatistics.getRechargeNum() - yesterdayStatistics.getRechargeNum()) / yesterdayStatistics.getRechargeNum()) * 100;
|
|
return (int) Math.round(rate);
|
|
}
|
|
/*
|
|
获取该日期该市场的周环比
|
|
*/
|
|
@Override
|
|
public Integer calculateWeekOverWeek(String market, Date date) {
|
|
//获取传入日期所在周的周一
|
|
Date thisWeekStart = getStartOfWeek(date);
|
|
//获取传入日期上一周的周一
|
|
Date lastWeekStart = addDays(thisWeekStart, -7);
|
|
// 获取本周周一至今天的充值人数总和
|
|
int thisWeekTotal = statisticsMapper.countRechargeNum(market, thisWeekStart, date);
|
|
// 获取上周同一时间段的充值人数总和
|
|
int lastWeekTotal = statisticsMapper.countRechargeNum(market, lastWeekStart, addDays(date, -7));
|
|
if (lastWeekTotal == 0) {
|
|
return 0; // 避免除以零的情况
|
|
}
|
|
double rate = ((double) (thisWeekTotal - lastWeekTotal) / lastWeekTotal) * 100;
|
|
return (int) Math.round(rate);
|
|
}
|
|
|
|
@Override
|
|
public Date addDays(Date date, int days) {
|
|
Calendar cal = Calendar.getInstance();
|
|
cal.setTime(date); //设置日期为传入的日期
|
|
cal.add(Calendar.DATE, days); //传入日期加上多少天
|
|
return cal.getTime(); //返回处理后的日期
|
|
}
|
|
|
|
@Override
|
|
public Date getStartOfWeek(Date date) {
|
|
// 将 Date 转换为 LocalDate
|
|
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
// 获取周一作为一周的第一天
|
|
DayOfWeek firstDayOfWeek = DayOfWeek.MONDAY;
|
|
|
|
// 返回所在周的第一天,转换回Date格式
|
|
return Date.from(localDate.with(firstDayOfWeek)
|
|
.atStartOfDay(ZoneId.systemDefault())
|
|
.toInstant());
|
|
}
|
|
|
|
|
|
}
|