feat(statistics): 添加营业概览统计功能

- 新增营业概览、收款构成、营业构成等统计接口和页面
- 实现订单数、营业额、优惠金额等统计指标
- 添加虚拟发货的物流方式
- 优化订单和充值相关查询方法
This commit is contained in:
pikachu1995@126.com
2025-08-26 17:32:16 +08:00
parent 09e6f4a1a1
commit b57e7813d6
13 changed files with 706 additions and 1 deletions

View File

@@ -19,7 +19,11 @@ public enum DeliveryMethodEnum {
/**
* "物流"
*/
LOGISTICS("物流");
LOGISTICS("物流"),
/**
* 虚拟发货
*/
VIRTUAL("虚拟发货");
private final String description;

View File

@@ -0,0 +1,55 @@
package cn.lili.modules.statistics.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 营业构成VO
* @author Bulbasaur
* @since 2025/08/25 7:07 下午
*/
@Data
public class BusinessCompositionDataVO {
//订单分类构成
@ApiModelProperty(value = "到店自提")
private Double storeSelf;
@ApiModelProperty(value = "快递发货")
private Double express;
@ApiModelProperty(value = "线上无需配送")
private Double online;
//营业收入
@ApiModelProperty(value = "商品销售")
private Double income;
@ApiModelProperty(value = "运费")
private Double freight;
@ApiModelProperty(value = "商品返现(分销返佣)")
private Double incomeBack;
@ApiModelProperty(value = "商品销售+费用构成")
private Double incomeComposition;
//退款统计
@ApiModelProperty(value = "退款订单笔数")
private Long refundOrderNum;
@ApiModelProperty(value = "退款金额")
private Double refund;
@ApiModelProperty(value = "退款率")
private Double refundRate;
//消费指标
@ApiModelProperty(value = "支付金额")
private Double pay;
@ApiModelProperty(value = "折后笔单价")
private Double price;
@ApiModelProperty(value = "支付人数")
private Long payNum;
@ApiModelProperty(value = "折后客单价")
private Double priceNum;
}

View File

@@ -0,0 +1,31 @@
package cn.lili.modules.statistics.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 概览数据
* @author Bulbasaur
* @since 2025/08/25 7:07 下午
*/
@Data
public class OverViewDataVO {
@ApiModelProperty(value = "营业额")
private Double turnover;
@ApiModelProperty(value = "优惠金额")
private Double discount;
@ApiModelProperty(value = "营业收入不含数值储值金额")
private Double incomeNoStoreValue;
@ApiModelProperty(value = "支付订单数")
private Long payOrderNum;
@ApiModelProperty(value = "新增充值金额")
private Double recharge;
@ApiModelProperty(value = "使用充值金额")
private Long rechargeUse;
}

View File

@@ -0,0 +1,26 @@
package cn.lili.modules.statistics.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 收款构成
*
* @author Bulbasaur
* @since 2025/08/25 7:07 下午
*/
@Data
public class SourceDataVO {
@ApiModelProperty(value = "支付方式")
private String payType;
@ApiModelProperty(value = "收款合计")
private Double total;
@ApiModelProperty(value = "营业收入")
private Double income;
@ApiModelProperty(value = "新增储值金额")
private Double recharge;
}

View File

@@ -1,6 +1,7 @@
package cn.lili.modules.statistics.mapper;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.vo.OrderSimpleVO;
import cn.lili.modules.statistics.entity.vo.OrderStatisticsDataVO;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
@@ -60,4 +61,24 @@ public interface OrderStatisticsMapper extends BaseMapper<Order> {
" FROM li_order o INNER JOIN li_order_item AS oi on o.sn = oi.order_sn ${ew.customSqlSegment} ")
IPage<OrderSimpleVO> queryByParams(IPage<OrderSimpleVO> page, @Param(Constants.WRAPPER) Wrapper<OrderSimpleVO> queryWrapper);
/**
* 查询已付款未全部退款的订单数量
*/
@Select("SELECT COALESCE(COUNT(DISTINCT order_sn), 0) FROM li_order_item ${ew.customSqlSegment} ")
Long getPayOrderNum(@Param(Constants.WRAPPER) Wrapper<OrderItem> queryWrapper);
/**
* 查询已付款未全部退款的订单金额
*/
@Select("SELECT COALESCE(SUM( oi.flow_price )- SUM( oi.refund_price ), 0) FROM li_order_item oi INNER JOIN li_order o ON o.sn=oi.order_sn ${ew.customSqlSegment} ")
Double getPayOrderPrice(@Param(Constants.WRAPPER) Wrapper<OrderItem> queryWrapper);
/**
* 查询商品价格
*/
@Select("SELECT COALESCE(SUM(goods_price), 0) FROM li_order_item ${ew.customSqlSegment} ")
Double getGoodsPrice(@Param(Constants.WRAPPER) Wrapper<OrderItem> queryWrapper);
@Select("SELECT COALESCE(SUM( oi.refund_price ), 0) FROM li_order_item oi INNER JOIN li_order o ON o.sn=oi.order_sn ${ew.customSqlSegment} ")
Double getRefundPrice(@Param(Constants.WRAPPER) Wrapper<OrderItem> queryWrapper);
}

View File

@@ -1,14 +1,17 @@
package cn.lili.modules.statistics.service;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.vo.OrderSimpleVO;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam;
import cn.lili.modules.statistics.entity.vo.OrderOverviewVO;
import cn.lili.modules.statistics.entity.vo.OrderStatisticsDataVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Date;
import java.util.List;
/**
@@ -34,6 +37,22 @@ public interface OrderStatisticsService extends IService<Order> {
* @return 订单总数量
*/
long orderNum(String orderStatus);
/**
* 获取订单总数量
*
* @param paymentMethod 支付方式
* @param dates 时间
*
* @return 订单总数量
*/
long orderNum(String paymentMethod, Date[] dates);
/**
* 获取所有优惠金额去除退款金额
* @param dates
* @return
*/
Double getDiscountPrice(Date[] dates);
/**
* 图表统计
@@ -51,4 +70,64 @@ public interface OrderStatisticsService extends IService<Order> {
* @return
*/
IPage<OrderSimpleVO> getStatistics(StatisticsQueryParam statisticsQueryParam, PageVO pageVO);
/**
* 获取付款订单数量 不含全部退款
*
* @param dates 时间
* @return 付款订单数量
*/
long getPayOrderNum(Date[] dates);
/**
* 获取付款订单金额去除退款金额
*
* @param dates 时间
* @param paymentMethodEnum 支付方式
* @param deliveryMethodEnum 配送方式
* @return 付款订单金额
*/
Double getPayOrderPrice(Date[] dates, PaymentMethodEnum paymentMethodEnum, DeliveryMethodEnum deliveryMethodEnum);
/**
* 获取商品价格
* @param dates 时间
* @return
*/
Double getGoodsPrice(Date[] dates);
/**
* 获取运费
* @param dates 时间
* @return
*/
Double getFreight(Date[] dates);
/**
* 获取分销返佣
* @param dates
* @return
*/
Double getDistribution(Date[] dates);
/**
* 获取退款订单数
* @param dates
* @return
*/
Long getRefundNum(Date[] dates);
/**
* 获取退款金额
* @param dates
* @return
*/
Double getRefundPrice(Date[] dates);
/**
* 获取退款率
* @param dates
* @return
*/
Double getRefundRate(Date[] dates);
}

View File

@@ -0,0 +1,47 @@
package cn.lili.modules.statistics.service;
import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam;
import cn.lili.modules.statistics.entity.vo.BusinessCompositionDataVO;
import cn.lili.modules.statistics.entity.vo.OrderOverviewVO;
import cn.lili.modules.statistics.entity.vo.OverViewDataVO;
import cn.lili.modules.statistics.entity.vo.SourceDataVO;
import java.util.Date;
import java.util.List;
/**
* 营业概览统计
*
* @author Bulbasaur
* @since 2025/08/25 7:31 下午
*/
public interface OverViewStatisticsService {
/**
* 获取营业概览统计
*
* @param statisticsQueryParam 统计参数
* @return 营业概览统计
*/
OverViewDataVO getOverViewDataVO(StatisticsQueryParam statisticsQueryParam);
/**
* 获取收款构成列表
*
* @param statisticsQueryParam 统计参数
* @return 收款构成列表
*/
List<SourceDataVO> getSourceDataVOList(StatisticsQueryParam statisticsQueryParam);
/**
* 获取营业构成列表
*
* @param statisticsQueryParam 统计参数
* @return 营业构成列表
*/
BusinessCompositionDataVO businessCompositionDataVO(StatisticsQueryParam statisticsQueryParam);
}

View File

@@ -6,10 +6,17 @@ import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.entity.enums.FlowTypeEnum;
import cn.lili.modules.order.order.entity.enums.OrderTypeEnum;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.order.order.entity.enums.RefundStatusEnum;
import cn.lili.modules.order.order.entity.vo.OrderSimpleVO;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam;
import cn.lili.modules.statistics.entity.vo.OrderOverviewVO;
import cn.lili.modules.statistics.entity.vo.OrderStatisticsDataVO;
@@ -38,6 +45,8 @@ import java.util.*;
@Service
public class OrderStatisticsServiceImpl extends ServiceImpl<OrderStatisticsMapper, Order> implements OrderStatisticsService {
/**
* 平台PV统计
*/
@@ -46,6 +55,8 @@ public class OrderStatisticsServiceImpl extends ServiceImpl<OrderStatisticsMappe
@Autowired
private StoreFlowStatisticsService storeFlowStatisticsService;
@Autowired
private OrderItemService orderItemService;
@Override
public OrderOverviewVO overview(StatisticsQueryParam statisticsQueryParam) {
@@ -104,6 +115,197 @@ public class OrderStatisticsServiceImpl extends ServiceImpl<OrderStatisticsMappe
return this.count(queryWrapper);
}
@Override
public long orderNum(String paymentMethod, Date[] dates) {
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(CharSequenceUtil.isNotEmpty(paymentMethod), Order::getPaymentMethod, paymentMethod);
queryWrapper.between(Order::getCreateTime, dates[0], dates[1]);
return this.count(queryWrapper);
}
@Override
public Double getDiscountPrice(Date[] dates) {
// 参数校验
if (dates == null || dates.length < 2) {
return 0.0;
}
// 构建查询条件:按时间范围过滤,排除全部退款的订单项
LambdaQueryWrapper<OrderItem> queryWrapper = new LambdaQueryWrapper<OrderItem>()
.ne(OrderItem::getIsRefund, RefundStatusEnum.ALL_REFUND.name())
.between(OrderItem::getCreateTime, dates[0], dates[1]);
List<OrderItem> orderItems = orderItemService.list(queryWrapper);
if (orderItems.isEmpty()) {
return 0.0;
}
Double totalDiscountPrice = 0.0;
for (OrderItem orderItem : orderItems) {
PriceDetailDTO priceDetailDTO = orderItem.getPriceDetailDTO();
if (priceDetailDTO == null) {
continue;
}
Double itemDiscountPrice = calculateItemDiscountPrice(priceDetailDTO);
if (RefundStatusEnum.NO_REFUND.name().equals(orderItem.getIsRefund())) {
// 未退款:计算全部优惠金额
totalDiscountPrice = CurrencyUtil.add(totalDiscountPrice, itemDiscountPrice);
} else {
// 部分退款:按比例计算剩余优惠金额
Double remainingDiscountPrice = calculateRemainingDiscountPrice(
itemDiscountPrice, orderItem.getNum(), orderItem.getReturnGoodsNumber());
totalDiscountPrice = CurrencyUtil.add(totalDiscountPrice, remainingDiscountPrice);
}
}
return totalDiscountPrice;
}
@Override
public long getPayOrderNum(Date[] dates) {
LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper=new LambdaQueryWrapper<>();
orderItemLambdaQueryWrapper.between(OrderItem::getCreateTime,dates[0], dates[1]);
orderItemLambdaQueryWrapper.ne(OrderItem::getIsRefund,RefundStatusEnum.ALL_REFUND.name());
return this.baseMapper.getPayOrderNum(orderItemLambdaQueryWrapper);
}
@Override
public Double getPayOrderPrice(Date[] dates, PaymentMethodEnum paymentMethodEnum, DeliveryMethodEnum deliveryMethodEnum) {
//查看付款金额
QueryWrapper queryWrapper = Wrappers.query();
queryWrapper.between("oi.create_time", dates[0], dates[1]);
queryWrapper.ne("oi.is_refund", RefundStatusEnum.ALL_REFUND.name());
if(paymentMethodEnum!=null){
queryWrapper.eq("o.payment_method",paymentMethodEnum.name());
}
if(deliveryMethodEnum!=null){
if(DeliveryMethodEnum.VIRTUAL.equals(deliveryMethodEnum)){
queryWrapper.eq("o.order_type", OrderTypeEnum.VIRTUAL.name());
}else{
queryWrapper.eq("o.delivery_method",deliveryMethodEnum.name());
}
}
return this.baseMapper.getPayOrderPrice(queryWrapper);
}
@Override
public Double getGoodsPrice(Date[] dates) {
LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper=new LambdaQueryWrapper<>();
orderItemLambdaQueryWrapper.between(OrderItem::getCreateTime,dates[0], dates[1]);
orderItemLambdaQueryWrapper.ne(OrderItem::getIsRefund,RefundStatusEnum.ALL_REFUND.name());
return this.baseMapper.getGoodsPrice(orderItemLambdaQueryWrapper);
}
@Override
public Double getFreight(Date[] dates) {
LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper=new LambdaQueryWrapper<>();
orderItemLambdaQueryWrapper.between(OrderItem::getCreateTime,dates[0], dates[1]);
orderItemLambdaQueryWrapper.ne(OrderItem::getIsRefund,RefundStatusEnum.ALL_REFUND.name());
List<OrderItem> orderItems=orderItemService.list(orderItemLambdaQueryWrapper);
Double freight=0D;
for (OrderItem orderItem:orderItems){
PriceDetailDTO priceDetailDTO=orderItem.getPriceDetailDTO();
freight=CurrencyUtil.add(freight,priceDetailDTO.getFreightPrice());
}
return freight;
}
@Override
public Double getDistribution(Date[] dates) {
LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper=new LambdaQueryWrapper<>();
orderItemLambdaQueryWrapper.between(OrderItem::getCreateTime,dates[0], dates[1]);
orderItemLambdaQueryWrapper.ne(OrderItem::getIsRefund,RefundStatusEnum.ALL_REFUND.name());
List<OrderItem> orderItems=orderItemService.list(orderItemLambdaQueryWrapper);
Double distributionCommission=0D;
for (OrderItem orderItem:orderItems){
PriceDetailDTO priceDetailDTO=orderItem.getPriceDetailDTO();
distributionCommission=CurrencyUtil.add(distributionCommission,priceDetailDTO.getDistributionCommission());
}
return distributionCommission;
}
@Override
public Long getRefundNum(Date[] dates) {
LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper=new LambdaQueryWrapper<>();
orderItemLambdaQueryWrapper.between(OrderItem::getCreateTime,dates[0], dates[1]);
orderItemLambdaQueryWrapper.eq(OrderItem::getIsRefund,RefundStatusEnum.ALL_REFUND.name());
return this.baseMapper.getPayOrderNum(orderItemLambdaQueryWrapper);
}
@Override
public Double getRefundPrice(Date[] dates) {
QueryWrapper queryWrapper = Wrappers.query();
queryWrapper.between("oi.create_time", dates[0], dates[1]);
queryWrapper.eq("oi.is_refund", RefundStatusEnum.ALL_REFUND.name());
return this.baseMapper.getRefundPrice(queryWrapper);
}
@Override
public Double getRefundRate(Date[] dates) {
QueryWrapper queryWrapper = Wrappers.query();
queryWrapper.between("create_time", dates[0], dates[1]);
Long orderNum= this.baseMapper.getPayOrderNum(queryWrapper);
return CurrencyUtil.mul(CurrencyUtil.div(this.getRefundNum(dates),orderNum),100);
}
/**
* 计算订单项的优惠金额
*/
private Double calculateItemDiscountPrice(PriceDetailDTO priceDetailDTO) {
Double discountPrice = priceDetailDTO.getDiscountPrice() != null ? priceDetailDTO.getDiscountPrice() : 0.0;
Double couponPrice = priceDetailDTO.getCouponPrice() != null ? priceDetailDTO.getCouponPrice() : 0.0;
return CurrencyUtil.add(discountPrice, couponPrice);
}
/**
* 计算部分退款后的剩余优惠金额
*/
private Double calculateRemainingDiscountPrice(Double totalDiscountPrice, Integer totalNum, Integer returnNum) {
if (totalNum == null || totalNum <= 0 || returnNum == null || returnNum < 0) {
return totalDiscountPrice;
}
Integer remainingNum = totalNum - returnNum;
if (remainingNum <= 0) {
return 0.0;
}
// 按剩余数量比例计算优惠金额
Double ratio = CurrencyUtil.div(remainingNum.doubleValue(), totalNum.doubleValue(), 4);
return CurrencyUtil.mul(totalDiscountPrice, ratio);
}
@Override
public List<OrderStatisticsDataVO> statisticsChart(StatisticsQueryParam statisticsQueryParam) {
Date[] dates = StatisticsDateUtil.getDateArray(statisticsQueryParam);

View File

@@ -0,0 +1,137 @@
package cn.lili.modules.statistics.serviceimpl;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam;
import cn.lili.modules.statistics.entity.vo.BusinessCompositionDataVO;
import cn.lili.modules.statistics.entity.vo.OrderOverviewVO;
import cn.lili.modules.statistics.entity.vo.OverViewDataVO;
import cn.lili.modules.statistics.entity.vo.SourceDataVO;
import cn.lili.modules.statistics.service.OrderStatisticsService;
import cn.lili.modules.statistics.service.OverViewStatisticsService;
import cn.lili.modules.statistics.util.StatisticsDateUtil;
import cn.lili.modules.wallet.service.RechargeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author Bulbasaur
* @since 2025/08/25 7:07 下午
*
*/
@Service
public class OverViewStatisticsServiceImpl implements OverViewStatisticsService {
@Autowired
private RechargeService rechargeService;
@Autowired
private OrderStatisticsService orderStatisticsService;
@Override
public OverViewDataVO getOverViewDataVO(StatisticsQueryParam statisticsQueryParam) {
Date[] dates = StatisticsDateUtil.getDateArray(statisticsQueryParam);
OverViewDataVO overViewDataVO = new OverViewDataVO();
//营业收入不含数值储值金额.订单扣除退款折扣后金额(不含储值充值)
overViewDataVO.setIncomeNoStoreValue(orderStatisticsService.getPayOrderPrice(dates,null,null));
//优惠金额.订单的优惠金额(扣除退款,不含储值充值)
overViewDataVO.setDiscount(orderStatisticsService.getDiscountPrice( dates));
//营业额.营业额=营业收入+优惠金额,订单扣除退款折扣前金额(不含储值充值)
overViewDataVO.setTurnover(CurrencyUtil.add(overViewDataVO.getIncomeNoStoreValue(), overViewDataVO.getDiscount()));
//支付订单数.按客户支付完成时间统计的成功付款的订单数(不含退款、储值充值)
overViewDataVO.setPayOrderNum(orderStatisticsService.getPayOrderNum(dates));
//新增充值金额.按客户支付完成时间统计的客户储值充值本金金额
overViewDataVO.setRecharge(rechargeService.getRecharge(dates,null));
//使用充值金额.使用储值支付本金金额:统计时间范围内,支付和退款成功的订单中,使用储值支付且扣除退款的金额
overViewDataVO.setRechargeUse(orderStatisticsService.orderNum(PaymentMethodEnum.WALLET.name(), dates));
return overViewDataVO;
}
@Override
public List<SourceDataVO> getSourceDataVOList(StatisticsQueryParam statisticsQueryParam) {
Date[] dates = StatisticsDateUtil.getDateArray(statisticsQueryParam);
List<SourceDataVO> sourceDataVOList=new ArrayList<>();
//微信
SourceDataVO sourceDataVO=new SourceDataVO();
sourceDataVO.setPayType(PaymentMethodEnum.WECHAT.paymentName());
sourceDataVO.setIncome(orderStatisticsService.getPayOrderPrice(dates,PaymentMethodEnum.WECHAT,null));
sourceDataVO.setRecharge(rechargeService.getRecharge(dates,PaymentMethodEnum.WECHAT));
sourceDataVO.setTotal(CurrencyUtil.add(sourceDataVO.getIncome(),sourceDataVO.getRecharge()));
sourceDataVOList.add(sourceDataVO);
//支付宝
SourceDataVO zhifubao=new SourceDataVO();
zhifubao.setPayType(PaymentMethodEnum.ALIPAY.paymentName());
zhifubao.setIncome(orderStatisticsService.getPayOrderPrice(dates,PaymentMethodEnum.ALIPAY,null));
zhifubao.setRecharge(rechargeService.getRecharge(dates,PaymentMethodEnum.ALIPAY));
zhifubao.setTotal(CurrencyUtil.add(zhifubao.getIncome(),zhifubao.getRecharge()));
sourceDataVOList.add(zhifubao);
//线下支付
SourceDataVO bankTransfer=new SourceDataVO();
bankTransfer.setPayType(PaymentMethodEnum.BANK_TRANSFER.paymentName());
bankTransfer.setIncome(orderStatisticsService.getPayOrderPrice(dates,PaymentMethodEnum.BANK_TRANSFER,null));
bankTransfer.setRecharge(rechargeService.getRecharge(dates,PaymentMethodEnum.BANK_TRANSFER));
bankTransfer.setTotal(CurrencyUtil.add(bankTransfer.getIncome(),bankTransfer.getRecharge()));
sourceDataVOList.add(bankTransfer);
//余额
SourceDataVO wallet=new SourceDataVO();
wallet.setPayType(PaymentMethodEnum.WALLET.paymentName());
wallet.setIncome(orderStatisticsService.getPayOrderPrice(dates,PaymentMethodEnum.WALLET,null));
wallet.setRecharge(rechargeService.getRecharge(dates,PaymentMethodEnum.WALLET));
wallet.setTotal(CurrencyUtil.add(wallet.getIncome(),wallet.getRecharge()));
sourceDataVOList.add(wallet);
return sourceDataVOList;
}
@Override
public BusinessCompositionDataVO businessCompositionDataVO(StatisticsQueryParam statisticsQueryParam) {
Date[] dates = StatisticsDateUtil.getDateArray(statisticsQueryParam);
BusinessCompositionDataVO businessCompositionDataVO=new BusinessCompositionDataVO();
//-----订单分类构成-----
businessCompositionDataVO.setStoreSelf(orderStatisticsService.getPayOrderPrice(dates,null, DeliveryMethodEnum.SELF_PICK_UP));
businessCompositionDataVO.setExpress(orderStatisticsService.getPayOrderPrice(dates,null, DeliveryMethodEnum.LOGISTICS));
businessCompositionDataVO.setOnline(orderStatisticsService.getPayOrderPrice(dates,null, DeliveryMethodEnum.VIRTUAL));
//-----营业收入-----
//商品销售
businessCompositionDataVO.setIncome(orderStatisticsService.getGoodsPrice(dates));
//运费
businessCompositionDataVO.setFreight(orderStatisticsService.getFreight(dates));
//商品返现(分销返佣)
businessCompositionDataVO.setIncomeBack(orderStatisticsService.getDistribution(dates));
//商品销售+费用构成
businessCompositionDataVO.setIncomeComposition(
CurrencyUtil.sub(CurrencyUtil.add(businessCompositionDataVO.getIncome(), businessCompositionDataVO.getFreight()),
businessCompositionDataVO.getIncomeBack()));
//-----退款统计-----
//退款订单笔数
businessCompositionDataVO.setRefundOrderNum(orderStatisticsService.getRefundNum(dates));
//退款金额
businessCompositionDataVO.setRefund(orderStatisticsService.getRefundPrice(dates));
//退款率
businessCompositionDataVO.setRefundRate(orderStatisticsService.getRefundRate(dates));
//-----消费指标-----
//支付金额
OrderOverviewVO overview=orderStatisticsService.overview(statisticsQueryParam);
businessCompositionDataVO.setPay(overview.getPaymentAmount());
//折后笔单价
businessCompositionDataVO.setPrice(CurrencyUtil.div(overview.getPaymentAmount(),overview.getPaymentOrderNum()));
//支付人数
businessCompositionDataVO.setPayNum(overview.getPaymentsNum());
//折后客单价
businessCompositionDataVO.setPriceNum(CurrencyUtil.div(overview.getPaymentAmount(),overview.getPaymentsNum()));
return businessCompositionDataVO;
}
}

View File

@@ -1,7 +1,12 @@
package cn.lili.modules.wallet.mapper;
import cn.lili.modules.order.order.entity.vo.PaymentLog;
import cn.lili.modules.wallet.entity.dos.Recharge;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* 预存款充值记录数据处理层
@@ -11,4 +16,13 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface RechargeMapper extends BaseMapper<Recharge> {
/**
* 获取会员预存款
*
* @return 会员预存款
*/
@Select("SELECT COALESCE(SUM(recharge_money), 0) FROM li_recharge ${ew.customSqlSegment}")
Double getRecharge(@Param(Constants.WRAPPER) Wrapper<Recharge> queryWrapper);
}

View File

@@ -2,10 +2,13 @@ package cn.lili.modules.wallet.service;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.order.trade.entity.vo.RechargeQueryVO;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.wallet.entity.dos.Recharge;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Date;
/**
* 预存款充值业务层
*
@@ -56,4 +59,10 @@ public interface RechargeService extends IService<Recharge> {
*/
void rechargeOrderCancel(String sn);
/**
* 获取周期内的充值金额
*
* @return
*/
Double getRecharge(Date[] dates, PaymentMethodEnum paymentMethodEnum);
}

View File

@@ -10,6 +10,7 @@ import cn.lili.common.utils.SnowFlake;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.order.trade.entity.vo.RechargeQueryVO;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.wallet.entity.dos.Recharge;
import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO;
import cn.lili.modules.wallet.entity.enums.DepositServiceTypeEnum;
@@ -17,6 +18,7 @@ import cn.lili.modules.wallet.mapper.RechargeMapper;
import cn.lili.modules.wallet.service.MemberWalletService;
import cn.lili.modules.wallet.service.RechargeService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -116,4 +118,15 @@ public class RechargeServiceImpl extends ServiceImpl<RechargeMapper, Recharge> i
this.updateById(recharge);
}
}
@Override
public Double getRecharge(Date[] dates, PaymentMethodEnum paymentMethodEnum) {
LambdaQueryWrapper<Recharge> queryWrapper = new LambdaQueryWrapper<Recharge>();
queryWrapper.eq(Recharge::getPayStatus, PayStatusEnum.PAID.name());
queryWrapper.between(Recharge::getPayTime, dates[0], dates[1]);
if(paymentMethodEnum!=null){
queryWrapper.eq(Recharge::getRechargeWay,paymentMethodEnum.name());
}
return this.baseMapper.getRecharge(queryWrapper);
}
}

View File

@@ -0,0 +1,67 @@
package cn.lili.controller.statistics;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam;
import cn.lili.modules.statistics.entity.vo.BusinessCompositionDataVO;
import cn.lili.modules.statistics.entity.vo.OverViewDataVO;
import cn.lili.modules.statistics.entity.vo.SourceDataVO;
import cn.lili.modules.statistics.service.OverViewStatisticsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 管理端,营业概览接口
*
* @author Bulbasaur
* @since 2025/08/25 7:31 下午
*/
@Slf4j
@Api(tags = "管理端,营业概览接口")
@RestController
@RequestMapping("/manager/statistics/overview")
public class OverViewStatisticsManagerController {
@Autowired
private OverViewStatisticsService overViewStatisticsService;
@ApiOperation(value = "获取营业概览统计")
@GetMapping
public ResultMessage<OverViewDataVO> overViewDataVO(StatisticsQueryParam statisticsQueryParam) {
try {
return ResultUtil.data(overViewStatisticsService.getOverViewDataVO(statisticsQueryParam));
} catch (Exception e) {
log.error("获取营业概览统计错误",e);
}
return null;
}
@ApiOperation(value = "收款构成列表")
@GetMapping("/source")
public ResultMessage<List<SourceDataVO>> sourceDataVOList(StatisticsQueryParam statisticsQueryParam) {
try {
return ResultUtil.data(overViewStatisticsService.getSourceDataVOList(statisticsQueryParam));
} catch (Exception e) {
log.error("收款构成列表错误",e);
}
return null;
}
@ApiOperation(value = "营业构成信息")
@GetMapping("/businessComposition")
public ResultMessage<BusinessCompositionDataVO> businessCompositionDataVO(StatisticsQueryParam statisticsQueryParam) {
try {
return ResultUtil.data(overViewStatisticsService.businessCompositionDataVO(statisticsQueryParam));
} catch (Exception e) {
log.error("营业构成信息",e);
}
return null;
}
}