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.
458 lines
18 KiB
458 lines
18 KiB
|
|
package com.example.demo.serviceImpl;
|
|
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.*;
|
|
import java.util.concurrent.TimeUnit;
|
|
import com.example.demo.Util.CheckIfNullUtil;
|
|
import com.example.demo.domain.vo.Meium;
|
|
import com.example.demo.domain.vo.Statistics;
|
|
import com.example.demo.domain.vo.Statisticss;
|
|
import com.example.demo.domain.vo.SumCoin;
|
|
import com.example.demo.mapper.StatisticsMapper;
|
|
import com.example.demo.sevice.StatisticsService;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.apache.ibatis.annotations.Param;
|
|
import org.springframework.cache.annotation.CacheConfig;
|
|
import org.springframework.cache.annotation.Cacheable;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.time.LocalDate;
|
|
import java.time.ZoneId;
|
|
import java.time.temporal.ChronoUnit;
|
|
import java.util.List;
|
|
|
|
@RequiredArgsConstructor
|
|
@Transactional
|
|
@Service
|
|
@CacheConfig(cacheNames = "statistics")
|
|
public class StatisticsServiceImpl implements StatisticsService {
|
|
private final StatisticsMapper statisticsMapper;
|
|
|
|
@Cacheable(key = "#root.method.name")
|
|
@Override
|
|
public Statistics getStatistics() {
|
|
Statistics statistics = new Statistics();
|
|
|
|
// 全年累计数据
|
|
Statistics yearStats = CheckIfNullUtil.defaultIfNull(statisticsMapper.getTotalYearCoin(), new Statistics());
|
|
statistics.setRechargeSumCoin(yearStats.getRechargeSumCoin());
|
|
statistics.setFreeSumCoin(yearStats.getFreeSumCoin());
|
|
statistics.setTaskSumCoin(yearStats.getTaskSumCoin());
|
|
statistics.setTotalSumCoin(yearStats.getTotalSumCoin());
|
|
|
|
// 昨日新增数据
|
|
Statistics yesterdayStats = CheckIfNullUtil.defaultIfNull(statisticsMapper.getYesterdayNewCoin(), new Statistics());
|
|
statistics.setRechargeYesterdaySumCoin(yesterdayStats.getRechargeYesterdaySumCoin());
|
|
statistics.setFreeYesterdaySumCoin(yesterdayStats.getFreeYesterdaySumCoin());
|
|
statistics.setTaskYesterdaySumCoin(yesterdayStats.getTaskYesterdaySumCoin());
|
|
statistics.setTotalYesterdaySumCoin(yesterdayStats.getTotalYesterdaySumCoin());
|
|
// 年累计充值人数
|
|
statistics.setRechargeCount(statisticsMapper.getYearRechargeCount());
|
|
|
|
// 本周和上周充值人数
|
|
int thisWeekCount = statisticsMapper.getRechargeCountThisWeek();
|
|
int lastWeekCount = statisticsMapper.getRechargeCountLastWeek();
|
|
statistics.setRechargeCountThisWeek(thisWeekCount);
|
|
statistics.setRechargeCountLastWeek(lastWeekCount);
|
|
|
|
// 周同比计算
|
|
BigDecimal weekOverWeekRate = BigDecimal.ZERO;//初始化为 0 表示如果没有足够的数据(如 lastWeekCount == 0),默认周同比增长率为 0。
|
|
if (lastWeekCount > 0) {
|
|
weekOverWeekRate = BigDecimal.valueOf((double) (thisWeekCount - lastWeekCount) / lastWeekCount * 100)//将计算结果转换为 BigDecimal 类型,保证高精度。
|
|
.setScale(2, BigDecimal.ROUND_HALF_UP); // 保留两位小数
|
|
}
|
|
statistics.setWeekOverWeekRate(weekOverWeekRate);
|
|
|
|
//今日和昨日充值人数
|
|
int todayCount = statisticsMapper.getRechargeCountToday();
|
|
int yesterdayCount = statisticsMapper.getRechargeCountYesterday();
|
|
int firstYesterdayCount = statisticsMapper.getFirstRechargeCountYesterday();
|
|
statistics.setRechargeCountToday(todayCount);
|
|
statistics.setRechargeCountYesterday(yesterdayCount);
|
|
statistics.setFirstRechargeCountYesterday(firstYesterdayCount);
|
|
|
|
//日环比计算
|
|
BigDecimal dayOverDayRate = BigDecimal.ZERO;
|
|
if (yesterdayCount > 0) {
|
|
dayOverDayRate = BigDecimal.valueOf((double) (todayCount - yesterdayCount) / yesterdayCount * 100).
|
|
setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
}
|
|
statistics.setDayOverDayRate(dayOverDayRate);
|
|
|
|
return statistics;
|
|
}
|
|
|
|
@Cacheable(key = "#root.method.name")
|
|
@Override
|
|
public Statisticss stats() {
|
|
Statisticss a = new Statisticss();
|
|
a.setCoinSystemSum(statisticsMapper.getCoinSystemSum());
|
|
a.setERPSum(statisticsMapper.getERPSum());
|
|
a.setHomilyChartSum(statisticsMapper.getHomilyChartSum());
|
|
a.setHomilyLinkSum(statisticsMapper.getHomilyLinkSum());
|
|
return a;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------//
|
|
@Cacheable(key = "#root.method.name")
|
|
public SumCoin getSumCoin() {
|
|
return statisticsMapper.getSumCoin();
|
|
}
|
|
|
|
@Cacheable(key = "#root.method.name")
|
|
@Override
|
|
public SumCoin getYearConsumeCoin() {
|
|
return statisticsMapper.getYearConsumeCoin();
|
|
}
|
|
|
|
@Cacheable(key = "#root.method.name")
|
|
@Override
|
|
public SumCoin getDayConsumeCoin() {
|
|
return statisticsMapper.getDayConsumeCoin();
|
|
}
|
|
|
|
@Override
|
|
public List<SumCoin> getMediuPayCoin() {
|
|
return List.of();
|
|
}
|
|
|
|
@Override
|
|
public List<SumCoin> getMediuConsumeCoin() {
|
|
return List.of();
|
|
}
|
|
|
|
|
|
public SumCoin getMess(Integer jwcode) {
|
|
return statisticsMapper.getMess(jwcode);
|
|
}
|
|
|
|
@Cacheable(key = "#root.method.name")
|
|
@Override
|
|
public List<SumCoin> getMediumAreaPay() {
|
|
return statisticsMapper.getMediumAreaPay();
|
|
}
|
|
|
|
@Cacheable(key = "#root.method.name")
|
|
@Override
|
|
public List<SumCoin> getMediumAreaConsume() {
|
|
return statisticsMapper.getMediumAreaConsume();
|
|
}
|
|
|
|
@Cacheable(key = "#root.method.name+ T(java.util.Objects).hashCode(#meium)")
|
|
@Override
|
|
public List<Meium> getMee(Meium meium) {
|
|
|
|
|
|
if (0 == (meium.getUpdateType())) {
|
|
if ("免费金币".equals(meium.getType())) {
|
|
return statisticsMapper.getBuyAndFree(meium.getSearchStartTime(), meium.getSearchEndTime());
|
|
} else if ("充值金币".equals(meium.getType())) {
|
|
return statisticsMapper.getBuyAndRecharge(meium.getSearchStartTime(), meium.getSearchEndTime());
|
|
} else if ("任务金币".equals(meium.getType())) {
|
|
return statisticsMapper.getBuyAndTask(meium.getSearchStartTime(), meium.getSearchEndTime());
|
|
} else {
|
|
return statisticsMapper.getBuy(meium.getSearchStartTime(), meium.getSearchEndTime());
|
|
}
|
|
|
|
} else if (1 == (meium.getUpdateType())) {
|
|
if ("免费金币".equals(meium.getType())) {
|
|
return statisticsMapper.getPayAndFree(meium.getSearchStartTime(), meium.getSearchEndTime());
|
|
} else if ("充值金币".equals(meium.getType())) {
|
|
return statisticsMapper.getPayAndRecharge(meium.getSearchStartTime(), meium.getSearchEndTime());
|
|
} else if ("任务金币".equals(meium.getType())) {
|
|
return statisticsMapper.getPayAndTask(meium.getSearchStartTime(), meium.getSearchEndTime());
|
|
} else {
|
|
return statisticsMapper.getPay(meium.getSearchStartTime(), meium.getSearchEndTime());
|
|
}
|
|
|
|
} else
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
@Override
|
|
public List<SumCoin> getMediu() {
|
|
return List.of();
|
|
}
|
|
|
|
|
|
// public List<SumCoin> getCoinTime( SumCoin sumcoin) {
|
|
//
|
|
// System.out.println(sumcoin+"-------sumcoin----");
|
|
// Date searchStartTime=sumcoin.getSearchStartTime();
|
|
// Date searchEndTime=sumcoin.getSearchEndTime();
|
|
// String updateType=sumcoin.getUpdateType();
|
|
//
|
|
//// //提供开始时间与结束时间
|
|
////// if(searchStartTime!=null && searchEndTime!=null){
|
|
//// //计算两个时间点之间的差值
|
|
//// long daysBetween = ChronoUnit.DAYS.between(searchStartTime, searchEndTime);
|
|
//
|
|
//// 提供开始时间与结束时间
|
|
//
|
|
//
|
|
// // 使用 Calendar 清除时间和时区的影响
|
|
// Calendar startCal = Calendar.getInstance();
|
|
// startCal.setTime(searchStartTime);
|
|
// startCal.set(Calendar.HOUR_OF_DAY, 0);
|
|
// startCal.set(Calendar.MINUTE, 0);
|
|
// startCal.set(Calendar.SECOND, 0);
|
|
// startCal.set(Calendar.MILLISECOND, 0);
|
|
//
|
|
// Calendar endCal = Calendar.getInstance();
|
|
// endCal.setTime(searchEndTime);
|
|
// endCal.set(Calendar.HOUR_OF_DAY, 0);
|
|
// endCal.set(Calendar.MINUTE, 0);
|
|
// endCal.set(Calendar.SECOND, 0);
|
|
// endCal.set(Calendar.MILLISECOND, 0);
|
|
//
|
|
// // 计算两个时间点之间的天数差异
|
|
// long diffInMillies = endCal.getTimeInMillis() - startCal.getTimeInMillis();
|
|
// long daysBetween = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);
|
|
//
|
|
//
|
|
// //年
|
|
// if(daysBetween>100 || searchStartTime==null & searchEndTime==null){
|
|
// if("消费".equals(updateType)){
|
|
// return statisticsMapper.getMediuConsumeCoin();
|
|
// }else if("充值".equals(updateType)){
|
|
// return statisticsMapper.getMediuPayCoin();
|
|
// }
|
|
//
|
|
// }else {
|
|
// if ("消费".equals(updateType)) {
|
|
// return statisticsMapper.getMediuCounsumeCoinyue(searchStartTime,searchEndTime);
|
|
// } else if ("充值".equals(updateType)) {
|
|
// return statisticsMapper.getMediuPayCoinyue(searchStartTime,searchEndTime);
|
|
// }
|
|
// }
|
|
// return null;
|
|
//
|
|
// }
|
|
|
|
//
|
|
// @Cacheable(key = "#root.method.name + #sumcoin.hashCode()")
|
|
// public List<SumCoin> getCoinTime(SumCoin sumcoin) {
|
|
// System.out.println(sumcoin + "-------sumcoin----");
|
|
//
|
|
// Date searchStartTime = sumcoin.getSearchStartTime();
|
|
// Date searchEndTime = sumcoin.getSearchEndTime();
|
|
// Integer updateType = sumcoin.getUpdateType();
|
|
//
|
|
// // 如果开始时间和结束时间都为空,则直接返回默认统计结果
|
|
// if (searchStartTime == null && searchEndTime == null) {
|
|
// if (1 == updateType) {
|
|
// return statisticsMapper.getMediuConsumeCoin(null, null);
|
|
// } else if (0 == updateType) {
|
|
// return statisticsMapper.getMediuPayCoin(null, null);
|
|
// }
|
|
// return null; // 或者抛出异常,取决于业务需求
|
|
// }
|
|
//
|
|
// // 如果只有其中一个时间为null,则可能需要处理或抛出异常,这里假设不允许这种情况
|
|
// if (searchStartTime == null || searchEndTime == null) {
|
|
// throw new IllegalArgumentException("开始时间和结束时间必须同时为空或不为空");
|
|
// }
|
|
//
|
|
// // 使用 Calendar 清除时间和时区的影响
|
|
// Calendar startCal = Calendar.getInstance();
|
|
// startCal.setTime(searchStartTime);
|
|
// startCal.set(Calendar.HOUR_OF_DAY, 0);
|
|
// startCal.set(Calendar.MINUTE, 0);
|
|
// startCal.set(Calendar.SECOND, 0);
|
|
// startCal.set(Calendar.MILLISECOND, 0);
|
|
//
|
|
// Calendar endCal = Calendar.getInstance();
|
|
// endCal.setTime(searchEndTime);
|
|
// endCal.set(Calendar.HOUR_OF_DAY, 0);
|
|
// endCal.set(Calendar.MINUTE, 0);
|
|
// endCal.set(Calendar.SECOND, 0);
|
|
// endCal.set(Calendar.MILLISECOND, 0);
|
|
//
|
|
// // 计算两个时间点之间的天数差异
|
|
// long diffInMillies = endCal.getTimeInMillis() - startCal.getTimeInMillis();
|
|
// long daysBetween = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);
|
|
//
|
|
// // 根据条件选择查询方法
|
|
// List<SumCoin> result = null;
|
|
//
|
|
// // 如果天数差大于100天
|
|
// if (daysBetween > 100) {
|
|
// if (1 == updateType) {
|
|
// result = statisticsMapper.getMediuConsumeCoin(searchStartTime, searchEndTime);
|
|
// } else if (0 == updateType) {
|
|
// result = statisticsMapper.getMediuPayCoin(searchStartTime, searchEndTime);
|
|
// }
|
|
// }
|
|
// // 如果天数差为0,即同一天
|
|
// else if (daysBetween == 0) {
|
|
// if (1 == updateType) {
|
|
// result = statisticsMapper.getMediuConsumeCoinday(searchEndTime, updateType);
|
|
// } else if (0 == updateType) {
|
|
// result = statisticsMapper.getMediuPayCoinday(searchEndTime, updateType);
|
|
// }
|
|
// }
|
|
// // 如果天数差小于100天,但不为0(即跨月或较短时间段)
|
|
// else {
|
|
// if (1 == updateType) {
|
|
// result = statisticsMapper.getMediuCounsumeCoinyue(searchStartTime, searchEndTime);
|
|
// } else if (0 == updateType) {
|
|
// result = statisticsMapper.getMediuPayCoinyue(searchStartTime, searchEndTime);
|
|
// }
|
|
// }
|
|
//
|
|
// // 如果查询结果为空或没有数据,返回默认的SumCoin对象
|
|
// if (result == null || result.isEmpty()) {
|
|
// result = Collections.singletonList(createDefaultSumCoin());
|
|
// }
|
|
//
|
|
// return result;
|
|
// }
|
|
//
|
|
// // 创建默认的 SumCoin 对象
|
|
// private SumCoin createDefaultSumCoin() {
|
|
// SumCoin defaultSumCoin = new SumCoin();
|
|
//
|
|
// defaultSumCoin.setRechargeSumCoin(BigDecimal.ZERO);
|
|
// defaultSumCoin.setFreeSumCoin(BigDecimal.ZERO);
|
|
// defaultSumCoin.setTaskSumCoin(BigDecimal.ZERO);
|
|
// // 获取当前日期并设置为字符串格式
|
|
// Date currentDate = new Date();
|
|
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d"); // "yyyy-M-d" 格式
|
|
// String formattedDate = sdf.format(currentDate); // 格式化日期为字符串
|
|
//
|
|
// // 设置当前日期
|
|
// defaultSumCoin.setDay(formattedDate);
|
|
// return defaultSumCoin;
|
|
// }
|
|
//}
|
|
|
|
|
|
@Cacheable(key = "#root.method.name + #sumcoin.hashCode()")
|
|
public List<SumCoin> getCoinTime(SumCoin sumcoin) {
|
|
System.out.println(sumcoin + "-------sumcoin----");
|
|
|
|
Date searchStartTime = sumcoin.getSearchStartTime();
|
|
Date searchEndTime = sumcoin.getSearchEndTime();
|
|
Integer updateType = sumcoin.getUpdateType();
|
|
|
|
// 如果开始时间和结束时间都为空,则直接返回默认统计结果,即全查
|
|
if (searchStartTime == null && searchEndTime == null) {
|
|
if (1 == updateType) {
|
|
return statisticsMapper.getMediuConsumeCoin(searchStartTime, searchEndTime);//前端没有选定时间,SQL会查询所有数据
|
|
} else if (0 == updateType) {
|
|
return statisticsMapper.getMediuPayCoin(null, null);
|
|
}
|
|
return null; // 或者抛出异常,取决于业务需求
|
|
}
|
|
|
|
// 如果只有其中一个时间为null,则可能需要处理或抛出异常,这里假设不允许这种情况
|
|
if (searchStartTime == null || searchEndTime == null) {
|
|
throw new IllegalArgumentException("开始时间和结束时间必须同时为空或不为空");
|
|
}
|
|
|
|
// 使用 Calendar 清除时间和时区的影响
|
|
Calendar startCal = Calendar.getInstance();
|
|
startCal.setTime(searchStartTime);
|
|
startCal.set(Calendar.HOUR_OF_DAY, 0);
|
|
startCal.set(Calendar.MINUTE, 0);
|
|
startCal.set(Calendar.SECOND, 0);
|
|
startCal.set(Calendar.MILLISECOND, 0);
|
|
|
|
Calendar endCal = Calendar.getInstance();
|
|
endCal.setTime(searchEndTime);
|
|
endCal.set(Calendar.HOUR_OF_DAY, 0);
|
|
endCal.set(Calendar.MINUTE, 0);
|
|
endCal.set(Calendar.SECOND, 0);
|
|
endCal.set(Calendar.MILLISECOND, 0);
|
|
|
|
// 计算两个时间点之间的天数差异
|
|
long diffInMillies = endCal.getTimeInMillis() - startCal.getTimeInMillis();
|
|
long daysBetween = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);
|
|
|
|
// 根据条件选择查询方法
|
|
List<SumCoin> result = new ArrayList<>();
|
|
List<SumCoin> queryResult = null;
|
|
|
|
// 如果天数差大于100天
|
|
if (daysBetween > 100) {
|
|
if (1 == updateType) {
|
|
return statisticsMapper.getMediuConsumeCoin(searchStartTime, searchEndTime);
|
|
} else if (0 == updateType) {
|
|
return statisticsMapper.getMediuPayCoin(searchStartTime, searchEndTime);
|
|
}
|
|
}
|
|
// 如果天数差为0,即同一天
|
|
else if (daysBetween == 0) {
|
|
if (1 == updateType) {
|
|
queryResult = statisticsMapper.getMediuConsumeCoinday(searchEndTime, updateType);
|
|
} else if (0 == updateType) {
|
|
queryResult = statisticsMapper.getMediuPayCoinday(searchEndTime, updateType);
|
|
}
|
|
}
|
|
// 如果天数差小于100天,但不为0(即跨月或较短时间段)
|
|
else {
|
|
if (1 == updateType) {
|
|
queryResult = statisticsMapper.getMediuCounsumeCoinyue(searchStartTime, searchEndTime);
|
|
} else if (0 == updateType) {
|
|
queryResult = statisticsMapper.getMediuPayCoinyue(searchStartTime, searchEndTime);
|
|
}
|
|
}
|
|
|
|
// 创建一个日期范围列表
|
|
List<Date> allDates = getDateRange(searchStartTime, searchEndTime);
|
|
|
|
// 将查询结果按日期映射,方便查找
|
|
Map<String, SumCoin> resultMap = new HashMap<>();
|
|
if (queryResult != null) {
|
|
for (SumCoin coin : queryResult) {
|
|
resultMap.put(coin.getDay(), coin);
|
|
}
|
|
}
|
|
|
|
// 填充没有数据的日期,生成完整的结果
|
|
for (Date date : allDates) {
|
|
String dateString = new SimpleDateFormat("yyyy-MM-dd").format(date);
|
|
if (!resultMap.containsKey(dateString)) {
|
|
result.add(createDefaultSumCoin(dateString));
|
|
} else {
|
|
result.add(resultMap.get(dateString));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// 获取日期范围的所有日期
|
|
private List<Date> getDateRange(Date startDate, Date endDate) {
|
|
List<Date> dates = new ArrayList<>();
|
|
Calendar startCal = Calendar.getInstance();
|
|
startCal.setTime(startDate);
|
|
Calendar endCal = Calendar.getInstance();
|
|
endCal.setTime(endDate);
|
|
|
|
while (!startCal.after(endCal)) {
|
|
dates.add(startCal.getTime());
|
|
startCal.add(Calendar.DAY_OF_YEAR, 1);
|
|
}
|
|
|
|
return dates;
|
|
}
|
|
|
|
// 创建默认的 SumCoin 对象,并设置日期
|
|
private SumCoin createDefaultSumCoin(String date) {
|
|
SumCoin defaultSumCoin = new SumCoin();
|
|
|
|
defaultSumCoin.setRechargeSumCoin(BigDecimal.ZERO);
|
|
defaultSumCoin.setFreeSumCoin(BigDecimal.ZERO);
|
|
defaultSumCoin.setTaskSumCoin(BigDecimal.ZERO);
|
|
defaultSumCoin.setDay(date);
|
|
|
|
return defaultSumCoin;
|
|
}
|
|
}
|