添加功能
This commit is contained in:
171
ruoyi-bussiness/src/main/java/com/ruoyi/cms/util/MathUtil.java
Normal file
171
ruoyi-bussiness/src/main/java/com/ruoyi/cms/util/MathUtil.java
Normal file
@@ -0,0 +1,171 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.ruoyi.cms.constant.enums.QueryTimeTypeEnum;
|
||||
import com.ruoyi.cms.domain.vo.QueryResultVo;
|
||||
import com.ruoyi.cms.domain.vo.TreadVo;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 数学工具
|
||||
*
|
||||
* @author 马宝龙
|
||||
* @date 2026/1/21
|
||||
*/
|
||||
public class MathUtil {
|
||||
private MathUtil() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 除以 10000
|
||||
*
|
||||
* @param n 原数
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigDecimal divideTenThousand(Long n) {
|
||||
if (Objects.isNull(n)) {
|
||||
return null;
|
||||
}
|
||||
BigDecimal bigDecimal = new BigDecimal(n.toString());
|
||||
return divideTenThousand(bigDecimal);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 除以 10000
|
||||
*
|
||||
* @param bigDecimal 原数
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigDecimal divideTenThousand(BigDecimal bigDecimal) {
|
||||
if (Objects.isNull(bigDecimal)) {
|
||||
return null;
|
||||
}
|
||||
String plainString = bigDecimal.divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP)
|
||||
.stripTrailingZeros().toPlainString();
|
||||
return new BigDecimal(plainString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算比率
|
||||
*
|
||||
* @param divisor 除数(分母)
|
||||
* @param dividend 被除数(分子)
|
||||
* @return 比率
|
||||
*/
|
||||
public static BigDecimal calculatePercentage(Long divisor, Long dividend) {
|
||||
BigDecimal divisorBigDecimal = Optional.ofNullable(divisor)
|
||||
.map(item -> new BigDecimal(item.toString())).orElse(null);
|
||||
BigDecimal dividendBigDecimal = Optional.ofNullable(dividend)
|
||||
.map(item -> new BigDecimal(item.toString())).orElse(null);
|
||||
return calculatePercentage(divisorBigDecimal, dividendBigDecimal);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算比率
|
||||
*
|
||||
* @param divisor 除数(分母)
|
||||
* @param dividend 被除数(分子)
|
||||
* @return 比率
|
||||
*/
|
||||
public static BigDecimal calculatePercentage(BigDecimal divisor, BigDecimal dividend) {
|
||||
if (null == dividend || BigDecimal.ZERO.compareTo(dividend) == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
} else {
|
||||
if (null == divisor || BigDecimal.ZERO.compareTo(divisor) == 0) {
|
||||
return new BigDecimal("100");
|
||||
} else {
|
||||
String plainString = dividend.multiply(new BigDecimal("100"))
|
||||
.divide(divisor, 2, RoundingMode.HALF_UP)
|
||||
.stripTrailingZeros().toPlainString();
|
||||
return new BigDecimal(plainString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算占比
|
||||
*
|
||||
* @param list 热力图数据
|
||||
*/
|
||||
public static void calculatePercentage(List<QueryResultVo> list) {
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
long totalCount = 0;
|
||||
for (QueryResultVo dto : list) {
|
||||
totalCount = totalCount + dto.getCount();
|
||||
}
|
||||
|
||||
for (QueryResultVo dto : list) {
|
||||
dto.setCountPercentage(calculatePercentage(totalCount, dto.getCount()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算同比和环比
|
||||
*
|
||||
* @param queryTimeType 查询时间类型
|
||||
* @param list 趋势数据列表
|
||||
*/
|
||||
public static void calculatePercentageGrowthRate(QueryTimeTypeEnum queryTimeType,
|
||||
List<TreadVo> list) {
|
||||
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 按月份正序排序
|
||||
list.sort(Comparator.comparingInt(TreadVo::getSort));
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
|
||||
TreadVo item = list.get(i);
|
||||
|
||||
long currentCount = Optional.ofNullable(item.getCurrentCount())
|
||||
.orElse(0L);
|
||||
long lastYearCount = Optional.ofNullable(item.getLastYearCount())
|
||||
.orElse(0L);
|
||||
// 年度不计算同比
|
||||
if (queryTimeType != QueryTimeTypeEnum.YEAR) {
|
||||
// 计算同比
|
||||
item.setYearOnYearGrowthDiff(currentCount - lastYearCount);
|
||||
if (0 == currentCount) {
|
||||
item.setYearOnYearGrowthRate(BigDecimal.ZERO);
|
||||
} else if (0 == lastYearCount) {
|
||||
item.setYearOnYearGrowthRate(new BigDecimal("100.00"));
|
||||
} else {
|
||||
item.setYearOnYearGrowthRate(calculatePercentage(lastYearCount, (currentCount - lastYearCount)));
|
||||
}
|
||||
}
|
||||
|
||||
// 计算环比
|
||||
long lastMonthCount;
|
||||
if (0 == i) {
|
||||
// 第一个取上期的最后一个数据
|
||||
lastMonthCount = Optional.ofNullable(list.get(list.size() - 1).getLastYearCount())
|
||||
.orElse(0L);
|
||||
} else {
|
||||
lastMonthCount = Optional.ofNullable(list.get(i - 1).getLastYearCount())
|
||||
.orElse(0L);
|
||||
}
|
||||
item.setLastMonthCount(lastMonthCount);
|
||||
item.setMonthOnMonthGrowthDiff(currentCount - lastMonthCount);
|
||||
if (0 == currentCount) {
|
||||
item.setMonthOnMonthGrowthRate(BigDecimal.ZERO);
|
||||
} else if (0 == lastMonthCount) {
|
||||
item.setMonthOnMonthGrowthRate(new BigDecimal("100.00"));
|
||||
} else {
|
||||
item.setMonthOnMonthGrowthRate(calculatePercentage(lastMonthCount, (currentCount - lastMonthCount)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user